前言

JSON Web Token是符合RFC7519标准的开放式行业标准方法,用于在双方之间安全地表示声明。

What is Jwt

Jwt可以分为三个部分, header, payload, signature, 它们之前通过.来分隔.

  • HEADER 描述生成signature的具体算法。
{
 “alg”: “HS256”,
 “typ”: “JWT”
}
  • PAYLOAD 所有的Jwt验证的声明都存储在这里。

  • SIGNATURE 是由headerpayload派生的字段.

下面我们来简单说下signature是如何产生的

  1. 用.合并base64UrlEncode后的headerpayload

    base64UrlEncode(header) + “.” + base64UrlEncode(payload)
    
  2. 对上面的产生的值和一个secret-key做 Hash, 使用的算法会描述在HEADER里.

    hash_value = hash([base64UrlEncode(header) + “.” + base64UrlEncode(payload)], secret-key)
    
  3. 然后再将上面产生的结果再进行一个bash64UrlEncode

    Signature = base64UrlEncode(hash_value)
    

: 因为secret-key仅有服务端知道,而且只能它可以基于一个有效的签名产生一个新的 token, 所以请你一定保护好secret-key的安全。

how it work

image

Jwt可以通过很多种认证机制来接入应用程序,最常见的方式是在每一个请求体头部添加认证 token 信息。

// eg:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0I joxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

是否可以更安全

: Jwt token的payload是明文存储的,所以较敏感的信息(比如:内部ip等),不要放在payload里。

我们知道secret-key对于我们而言很重要,倘若secret-key会带来很大的安全隐患. 可以使用RS256非对称加密算法通过私钥签发一个token, 公钥来验证token的有效性。 私钥只有服务端知道,公钥可以被app/client,甚至可以被任何人访问.

对于三方客户端需要验证Jwt token是否为它们签发的,使用非对称加密是有用的。 如果服务端使用对称加密(比如HS256)签发Jwt token, 如果三方客户端需要认证token的有效的话,就不得不共享secret-key。这样也就增加了secret-key泄漏的风险。

可能你会说,对于三方客户端接入的情况下,不验证token的有效性不就不存在泄漏secret-key的风险吗? okay, 我们下面来说下不验证的另一种风险:

服务端直接相信Jwt token header里的数据,而不验证签发token使用算法的有效性,黑客可以修改Jwt tokenheader里的算法从RS256HS256, 然后再用公钥为token生成一个HMAC签名。服务器现在会将此token视为使用“HS256”算法生成的token,并使用其公钥对其进行解码和验证。

另外: 避免被暴力破解,当使用HS256的算法时,推荐使用256字符作为secret-key

是否可以自动延长过期时间

如果你想延长token,Jwt token自身并不能很好的解决这个问题,Auth0则可以很好的解决这个问题。

你可以自定义一个刷新接口,当token快过期时,重新生成一个新的token并继续使用。

如何使用

你可以从这里Jwt.io获取到相应的签名及验证库

示例

这里提供了一个基于go语言的demo, 希望对你有所帮助。

参考

  1. SECURITY ISSUES IN JWT AUTHENTICATION
  2. JWT (JSON Web Token) automatic prolongation of expiration