转载 阮一峰
https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
JWT 原理
服务器验证通过后,返回一个JSON对象,返回给Client,如下:
1 | { |
后续Client与Server通信携带此信息,Server通过此信息锁定对应的用户,Server不保存Session有关信息,且无状态,这样容易扩展.
JWT 数据结构
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiY3JlYXRlZCI6MTU4MTE3MjQwOTE5NCwiZXhwIjoxNTgxMjM2NDQyfQ.xRw2sP3RGXoUbioUJolFOMRRtm0d-HpYK5jYdysRNQs8m53FKoGR8cz7b0dpw2bQeHTGxlOC-dohohzaPysu2A
由三部分组成,以.
进行分隔:
- Header(头部)
- Payload(负载)
- signature(签名)
Header
1 | { |
由两部分组成:
- token类型,固定为jwt
- 签名算法
之后此JSON对象再由Base64Url进行编码.
Payload
Payload也是一个JSON对象,用来存放实际需要传递的数据.JWT规定了7个官方字段:
- iss(issuer):签发人
- exp(expiration time):过期时间
- sub(subject):主题
- aud(audience):受众
- nbf(Not before):生效时间
- iat(Issue at):签发时间
- jti(JWT ID):编号
除了官方字段,还可以定义私有字段:
1 | { |
这部分也是由Base64Url进行编码,注意JWT默认是不进行加密的.
Signature
Signature是对前两个部分的签名,防止数据篡改.
根据仅服务器知道的密钥secret以及header中的签名算法,按照以下公式生成签名:
1 | HMACSHA256( |
得到签名后,将三部分使用.
连接在一起即可以返回个Client
Base64Url
由于JWT可能作为URL中一部分,如:api.example.com/?token=xxx
.+
,/
和=
在URL中有特殊含义,所以要被替换掉,=
被省略,+
被替换成-
,/
被替换成_
,这就是Base64Url算法.
JWT 使用
一般地,在HTTP请求的Header中添加:
1 | Authorization: Bearer <token> |
也可以通过其他方式传递token信息
JWT 特点
JWT 默认是不加密,但也是可以加密的.生成Token后,可以用密钥再加密一次.
JWT 不加密的情况下,不能将秘密数据写入JWT.
JWT 不仅可以用于认证,也可以用于交换信息.有效使用 JWT,可以降低服务器查询数据库的次数.
JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限.也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑.
JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限.为了减少盗用,JWT 的有效期应该设置得比较短.对于一些比较重要的权限,使用时应该再次对用户进行认证.
为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输.