JSON Web Token (JWT)
共 2457字,需浏览 5分钟
·
2022-01-26 13:28
简介
JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方法,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。
组成部分
JSON Web Token由三个部分组成,使用(.)分割。
Header
Payload
Signature
因此JWT的格式为:xxxx.yyyy.zzzz
第一部分Header
通常包括两部分:令牌的类型(即JWT),以及使用的哈希算法(如HMAC SHA256或RSA)。
{
"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注册表
https://www.iana.org/assignments/jwt/jwt.xhtml
中定义它们,或者将其定义为包含防冲突命名空间的URI。
Private claims
这些是为共享使用它们的各方之间共享信息而创建的自定义声明。
例如
{
"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 工具测试签名和验签名。
https://jwt.io/#debugger-io
如何使用JWT
获取JWT并将其用于访问API或资源:
客户端从授权服务器登录
登录成功后授权服务器下发JWT令牌返回给客户端
客户端使用JWT令牌访问受保护的API资源服务器
请注意,使用签名的令牌,令牌中包含的所有信息都会暴露给用户或其他方(因使用的是Base64可以反编译获得原文),即使他们无法更改其中的数据,但不应将机密信息放入令牌中,由于缺乏安全性,不应该将敏感的会话数据存储在浏览器中。
在身份验证中,当用户使用其凭据成功登录时,将返回JSON Web Token。由于令牌是凭据,因此必须格外小心以防止安全问题。通常,令牌的保留时间不应超过要求的时间。
每当用户想要访问受保护的路由或资源时,用户代理应发送JWT,通常在使用Bearer模式的Authorization header中。
header的内容应如下所示: Authorization: Bearer
在某些情况下,这可以是无状态授权机制。服务器的受保护路由将在header中检查有效的JWT,如果存在,则将允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库中某些操作的需求,尽管并非总是如此。
如果令牌是在header中发送的,则跨域资源共享(CORS)不会成为问题,因为它不使用cookie。
总结
JSON Web Token(简称JWT)使用点(.)分隔三个Base64加密部分拼接在一起的字符串。
优点
轻量跨语言,使用字符串传输,不同开发语言系统都能使用
无状态,无需消耗缓存或其他数据存储保存状态
可跨域
可承载数据传输到不同系统,减少数据库的访问
可设置有效时间,在网关层/入口拦截器处理判断
签名和承载数据不可更改
缺点
承载数据完全暴露
无状态,不能有效管理token,需要等有效时间失效
有效时间续期问题
扩展
现在开发的系统是生成一个token(如UUID字符串),保存在缓存中,由服务器管理,校验和存储需要一些资源,当大量请求的时候后端会有一些压力。
因此参考了JWT的特性,把token字符串改为JWT的形式,token放在缓存,token状态因业务问题还是需要保留。这样的好处是保持业务不变,利用JWT的承载数据校验有效时间和身份等判断,减少与缓存的交互压力,可以很大程度有效过滤掉无用的token请求(虽然没了JWT的无状态等特性)。
source://winskin.github.io/2020/03/29/2020-03-29-JWT简介
分享&在看