0%

JWT简介

JSON Web Token (JWT)

参考资料:Introduction to JSON Web Tokens

简介

JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方法,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。

组成部分

JSON Web Token由三个部分组成,使用(.)分割。

  • Header
  • Payload
  • Signature

因此JWT的格式为:xxxx.yyyy.zzzz

第一部分Header

通常包括两部分:令牌的类型(即JWT),以及使用的哈希算法(如HMAC SHA256或RSA)。

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

然后,这个JSON是Base64Url编码形成JWT的第一部分。

第二部分Payload

通常包括claims, claims是关于实体(通常是用户)和附加元数据的声明。

这里有三个类型的声明:

  • reserved
  • public
  • private

Reserved claims

这些是一组预定义的声明,不是强制性的,而是建议的,以提供一组有用的,可互操作的声明。其中有些是:

  • iss (issuer)
  • exp (expiration time)
  • sub (subject)
  • aud (audience)
  • 其他

PS请注意,声明名称只有三个字符,因为JWT意味着紧凑。

Public claims

这些可以由使用JWT的人随意定义。但为避免冲突,应在
IANA JSON Web Token注册表
中定义它们,或者将其定义为包含防冲突命名空间的URI。

Private claims

这些是为共享使用它们的各方之间共享信息而创建的自定义声明。

例如

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

该payload被Base64Url编码以形成JSON Web令牌的第二部分。

第三部分Signature

创建签名部分,必须使用以下3个数据根据header中指定的算法, 并签名用于验签。

  • base64编码的header
  • 编码的payload
  • 一个secret

例如:如果要使用HMAC SHA256算法,将以以下方式创建签名:

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

最后拼接起来

输出是三个由点(.)分隔的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递这些字符串,与基于XML的标准(例如SAML)相比,它更紧凑。

下面这个就是编码签名后的JWT结果字符串:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c.

可以使用JWT Debug 工具测试签名和验签名。

如何使用JWT

获取JWT并将其用于访问API或资源:

  • 客户端从授权服务器登录
  • 登录成功后授权服务器下发JWT令牌返回给客户端
  • 客户端使用JWT令牌访问受保护的API资源服务器

请注意,使用签名的令牌,令牌中包含的所有信息都会暴露给用户或其他方(因使用的是Base64可以反编译获得原文),即使他们无法更改其中的数据,但不应将机密信息放入令牌中,由于缺乏安全性,不应该将敏感的会话数据存储在浏览器中。

在身份验证中,当用户使用其凭据成功登录时,将返回JSON Web Token。由于令牌是凭据,因此必须格外小心以防止安全问题。通常,令牌的保留时间不应超过要求的时间。

每当用户想要访问受保护的路由或资源时,用户代理应发送JWT,通常在使用Bearer模式的Authorization header中。
header的内容应如下所示: Authorization: Bearer <token>

在某些情况下,这可以是无状态授权机制。服务器的受保护路由将在header中检查有效的JWT,如果存在,则将允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库中某些操作的需求,尽管并非总是如此。

如果令牌是在header中发送的,则跨域资源共享(CORS)不会成为问题,因为它不使用cookie。

总结

JSON Web Token(简称JWT)使用点(.)分隔三个Base64加密部分拼接在一起的字符串。

优点

  1. 轻量跨语言,使用字符串传输,不同开发语言系统都能使用
  2. 无状态,无需消耗缓存或其他数据存储保存状态
  3. 可跨域
  4. 可承载数据传输到不同系统,减少数据库的访问
  5. 可设置有效时间,在网关层/入口拦截器处理判断
  6. 签名和承载数据不可更改

缺点

  1. 承载数据完全暴露
  2. 无状态,不能有效管理token,需要等有效时间失效
  3. 有效时间续期问题

扩展

现在开发的系统是生成一个token(如UUID字符串),保存在缓存中,由服务器管理,校验和存储需要一些资源,当大量请求的时候后端会有一些压力。

因此参考了JWT的特性,把token字符串改为JWT的形式,token放在缓存,token状态因业务问题还是需要保留。这样的好处是保持业务不变,利用JWT的承载数据校验有效时间和身份等判断,减少与缓存的交互压力,可以很大程度有效过滤掉无用的token请求(虽然没了JWT的无状态等特性)。