【Web】什么是 JWT

176 阅读3分钟

JWT,即 JSON Web Token,是一种跨域认证的解决方案,本文将详细介绍 JWT 的使用场景,原理和数据结构。


随着服务器集群或者跨域的服务导向架构的流行,对于传统的 Cookie Session 的认证方式,要求 session 数据在多个服务器中共享。一种解决方式是将 session 数据持久化,保存在数据库,但是这样会带来很大的工程量,同时如果持久层挂了,会单机失败。

另一种新的解决方式是,服务器不再保存 session 数据,而是将所有的数据都保存在客户端,每次请求的时候发回给服务器。JWT 便是这样一种跨域认证解决方案

JWT 是一种基于JSON 的开放标准(RFC 7519),用作在网络应用环境间安全地传递信息。这种 token 被设计为紧凑而安全,特别适用于分布式站点的单点登录(SSO)场景

使用场景

  1. 认证 这是 JWT 最常用的情景,作为跨域认证的凭证。
  2. 数据传输 因为 JWT 可以使用非对称加密方式生成签名,所以可以用来知道发送者是谁,同时验证信息是否被修改。

JWT 的原理

服务器对客户端进行认证后,生成一个 JSON 对象,即 JWT,发送给用户。

之后,每次用户给服务器发送请求时,都需要发回这个 JSON 对象。服务器通过这个 JSON 对象认证用户身份。

JWT 的数据结构

image.png

JWT 由三部分组成,中间使用 , 分隔,即 Header.Payload.Signature

  1. 头部 Header
  2. 负载 Payload
  3. 签名 Signature

头部

头部是一个 JSON 对象,一般包括两部分,token 的类型,即 JWT,和签名的算法,比如(HMAC SHA256RSA)。这一部分要使用 Base64Url 转化成字符串。

{ "alg": "HS256", "typ": "JWT" }

负载

负载也是一个 JSON 对象,用来放实际需要传输的数据,这一部分也要使用 Base64Url 转化成字符串。官方定义了7个字段,推荐使用但是不强制。

  • iss (issuer):签发人
  • exp (expiration time):过期时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号

除此之外,还可以自己定义字段。

JWT 默认是不加密的,所以最好不要把秘密的信息放在这部分。

签名

签名部分是对强两个部分的签名,防止数据篡改。

  1. 指定一个密钥(只有服务器知道)
  2. 使用头部中 alg 指定的签名算法产生签名。公式为: image.png

总结

把使用 Base64Url 编码的头部和负载使用 . 连接,再加上计算出来的签名,就是完整的 JWT 啦。可以使用 jwt.io Debugger 感受一下 JWT 的生成和解码。

JWT 的使用方式

因为 token 是凭证,因此需要非常小心,防止安全问题。一般来说,按必要的最短时间保存令牌。

客户端接收到 JWT 之后,可以保存在 Cookie 中,也可以保存在 localStorage 中。

之后,每次客户端和服务器通信,都需要带上 JWT。有两种方式:

  1. 放在 Cookie 中,但是这样无法跨域
  2. 放在 HTTP 请求头中的 Authorization字段,使用 Bearer 模式 Authorization: Bearer <token>

参考资料

  1. Introduction to JSON Web Tokens
  2. JSON Web Token 入门教程