前后端 JSON Web Token

JSON Web Token,JWT,是一种身份验证解决方案。

一、基于 Session 的身份验证

1. 验证方式

具体请看:

Java Web Session

客户端接收请求后,当请求中附带了 session_id,且可以根据 session_id 找到对应的 Session 时,才正确返回响应。

2. 缺点

在传统做法中,Session 会被放置于服务器内存之上。当后端为多服务器部署,这种做法将会存在问题,不同服务器之间无法共享 Session。

常见的解决方法有:

  • Session Sticky:将用户与服务器绑定,每个用户都始终只与一台服务器进行通信
  • 将 Session 集中存储

二、基于 JWT 的身份验证

  • 当用户登陆后,后端将会生成一串 JSON,这串 JSON 就是 JWT
  • 后端将 JWT 发送给客户端,并要求客户端在每次请求中携带
  • 客户端再次发送请求时,将会携带 JWT
  • 后端接收请求后,对 JWT 进行校验,当且仅当 JWT 通过校验时,才正确返回响应

三、JWT

1. JWT 的结构

实际的 JWT 大概长这样:

JWT 由三个部分组成,三个部分用 . 进行分隔。三个部分依次为:

  • 头部
  • 负载
  • 签名

因此,JWT 的结构是:

1
头部.负载.签名

2. 头部

头部对象中包含了 JWT 的描述信息,包括签名的算法、token 的类型。通常为:

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

将头部对象转为 JSON 并使用 Base64URL 加密,便成为了头部部分。

3. 负载

负载对象中存储着实际需要传递的数据,可以自定义字段并放入。

将负载对象转为 JSON 并使用 Base64URL 加密,便成为了负载部分。

4. 签名

签名部分是对前两部分的签名,它将根据一串(仅服务器可见而用户不可知)密钥、头部、负载等三个部分加密产生。

四、JWT 的校验机制

服务器收到 JWT 后,通过已知的密钥对 JWT 进行校验,判断 JWT 是否被篡改。

如果校验失败,则可以认定该 JWT 被人为修改,其中的头部或负载被恶意改动。

由于用户不知道密钥,因此在修改头部和负载后不能对签名部分做相应修改。

服务器接收到被篡改后的 JWT,能够轻易地发现签名与头部和负载不符,从而得知 JWT 的真伪。

五、JWT 的特点

  • JWT 只是简单加密,因此不应在其中放入敏感信息

  • 由于 JWT 中包含了数据,因此在 JWT 通过校验后便可以将其中的信息拿来使用,减少对数据库的查询

  • 由于服务器不保存对 JWT 的认证信息,因此 JWT 一旦签发便会一直有效,直至过期

    除非服务器部署额外的逻辑

  • JWT 一旦泄露,任何人都可以通过它获取认证,因此其有效期应该尽量设置得更短

参考