重拾 JWT
date
Feb 28, 2024
slug
relearn-jwt
status
Published
tags
JWT
Access Token
Refresh Token
summary
JWT 知识点总结
type
Post
什么是 JWT
- JSON Web Token 是一个开放标准(RFC 7519)
- 定义了一种紧凑且独立的方式,可以将信息做为 JSON 对象进行安全传输
- 该信息是可以被信任的,因为该信息产生时经过了数字签名
JWT 构成
- 头部(Header)
- 有效载荷(Payload)
- 签名(Signature)
示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
wL7ARAXUnUQwUJCw9Hem0dSfB0ZCdAyBi8-bOjBcgiI
上述 JWT 中三部分已
.
为分割符,按顺序排列Header
示例:
{
"alg": "HS256",
"typ": "JWT"
}
签名转 base64UrlEncode 后值为:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
alg
⇒ Signature or encryption algorithm,即签名算法。常用算法为:HMAC SHA256、RSA
typ
⇒ token 类型,固定为 JWT
Payload
示例:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
签名转 base64UrlEncode 后值为:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
sub
⇒ Subject (whom the token refers to),即 token 指向。一般设置为用户 ID
name
⇒ Name,即用户名
iat
⇒ Issued at (Time that the JWT was created),即创建时间
exp
⇒ Expires at (The expiration time of the JWT),过期时间
Payload 中的数据可以自定义字段名以及字段值
Signature
对 Header 以及 Payload 进行签名保证 Token 在传输过程中没有被篡改和损坏
示例
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
流程
主要工作在于:
- 第一次接受 login 请求后后端生成 JWT
- 前端根据返回的 JWT,将其存储在
localstorage
每次请求将其放入请求头字段Authorization
中Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.wL7ARAXUnUQwUJCw9Hem0dSfB0ZCdAyBi8-bOjBcgiI
- 后续请求到达后端后,需要手动从请求中拿出
Authentication
调用验证方法对 JWT 进行校验
不同后端对应的操作各不相同。
注意点
- 性能
因为 Payload 支持自定义所以很可能存入大量数据导致每次请求头较大,尽量保持 Payload 简单
- 时效性
JWT 设置过期时间后不能像
sid
(session id)那样手动清除后重新生成,必须需要等到 JWT 过期后重新生成。目前常见做法是在判断 token 过期时读 token 记录,如果被删除那么重新登陆。access_token
& refresh_token
流程
注意点
在其中2、3、4步中都有可能发生手动删除库中
token
数据的情况,常见做法是在判断 token
过期时读 token
记录,如果被删除那么重新登陆。基于这个思路那么建议如下:token
记录存储在内存数据库中(redis)要好于存储在数据库中
- 开发、测试、灰度环境保留该逻辑,生产环境通过环境变量隐藏该逻辑 🤣
参考
- JWT 在线验证
- 在线生成 secret
- APIFOX 自动设置
access_token