notes

JWT有什么用

JWT解决用户认证的问题,在用户登录的时候,客户端发起登录请求,服务端就可以返回一个JWT token,客户端在之后的请求中都带上这个token(一般是放在请求头的 Authorization 字段中),服务端就能知道是哪个用户了,实现服务端无状态

JWT结构

一个JWT token大概是长这样子的,是一个很长的字符串,分为3段,中间用.分隔,每个部分都是经过base64编码过的,

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

前两部分可以解码得出有效的json,最后一部分是通过一定算法作用在前两部分得出的签名

{"alg":"HS256","typ":"JWT"}.{"sub":"1234567890","name":"John Doe","iat":1516239022}.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

第一部分叫做 Header,Header 包含了 JWT 的一些元信息。

在 Header 中,alg是必须指定的值,他表示 JWT 的签名方式,例子中 JWT 使用的是 HS256 进行签名,也就是使用 SHA-256 作为摘要算法。常见的选择还有 RS256,ES256 等等。总结一下:

除了 alg ,官方还定义了一些其他的 key ,这里就不详细讲了。

Payload

第二部分是 Payload Payload 里面存的是一些有意义的数据,上面例子中解码后的数据如下:

{"sub":"1234567890","name":"John Doe","iat":1516239022}

和 Header 类似, Payload 中也有一些预定义的 key ,我们称他们为 claim。常见的预定义的 key 包括:

除了官方字段,开发者也可以自定义私有字段,比如里面的 name 就是私有字段。

但是注意 Payload 是不加密的,不要把隐私信息放入 Payload 中。

Signature

最后一部分是签名(Signature),签名是对 Header 和 Payload 的原文进行 base64 编码,然后用.连接,最后扔给签名算法进行签名,签名得到的算法再进行 base64 编码,就能得到签名了。

伪代码:

// 比如使用 RS256 签名:
let 签名数据: Data = RS256签名算法(Base64Url(string: Header).Base64Url(string: Payload), 私钥)
let 签名: String = Base64Url(data: 签名数据)

最后,再把三部分用.连接起来,就是我们看到的 JWT 了。

使用中的注意事项

失效时间

JWTtoken一般有两个失效时间:

一个是token本身的失效时间,这个很好理解,就是过了这个时间token就失效了。

还有一个是token过期后,再次刷新的有效期,也就是token过期后,你还有一段时间可以重新刷新,服务端会返回一个新token。

参考自喵神的文章