生成JWT令牌 JWT 是 JSON Web Token 的缩写,直译就是 “基于 JSON 的网络令牌”。
部分 内容说明 例子
Header 令牌类型 + 签名算法 `{"alg":"HS256","typ":"JWT"}`
Payload 声明(标准 + 自定义) {"sub":"123","name":"aa","exp":1696545600}`
Signature 防篡改签名 `HMACSHA256(base64Url(header) + '.' + base64Url(payload), 密钥)`
为什么用它
1.
无状态:服务器签完即可,不用保存会话。
2.
跨域/跨服务:在微服务、移动端、单页应用里随意传。
3.
自包含:载荷里直接带用户名、角色、过期时间等,一次验证即可。
常见流程
1.
用户登录 → 服务器验证账号密码。
2.
服务器生成 JWT 并签名 → 返回给前端。
3.
前端后续请求在 Header 里带
Authorization: Bearer <JWT>
4.
服务器用密钥验签 → 通过就认为是合法用户,不再查库。
Claims 直译 “声明”,在 JWT 里就是 “这张令牌里携带的数据” 的统称。 宣称;声称;获得;要求(拥有)
它其实是一份 JSON 对象,里面一个个键值对都叫一条 claim(声明),用来描述 “谁、什么时候、什么权限、有效期多久” 等信息。
两种声明
1.
标准声明(RFC 7519 规定,可选)
| 字段 | 含义 | |------|------| | iss (Issuer) | 签发者 | |
sub (Subject) | 主题(通常是用户 ID) | | aud (Audience) | 受众
| | exp (ExpiresAt) | 过期时间(Unix 秒) | | nbf (NotBefore)
| 在此之前不可用 | | iat (IssuedAt) | 签发时间 | | jti (JWT ID) | 令牌唯一编号 |
2.
自定义声明(自己随便加)
例如 Go 代码里写的:
go
type Claims struct {
UserID string `json:"userID"` // 自定义
Roles []string `json:"roles"` // 自定义
jwt.StandardClaims // 标准声明全部嵌入
}
最终生成的 Payload 长这样:
json
{
"userID": "42",
"roles": ["admin"],
"exp": 1696627200,
"iat": 1696540800,
"iss": "myapp"
}
Payload(中文常叫“有效载荷”或“净荷”)就是真正想要传输、保存或处理的那些数据,
区别于为了完成传输而额外加上的“包装/控制/元数据”。
Header 负责“怎么送”,Payload 负责“送什么”。
场景 Header / 包装 Payload
HTTP 状态行 + 请求/响应头 请求体/响应体(JSON、HTML、文件…)
TCP/IP 各层首部(IP 头、TCP 头) 真正的应用数据 JWT
Header + Signature Payload(存放用户 ID、角色、过期时间等声明)
消息队列 消息属性(路由键、时间戳) 业务 JSON / Protobuf
文件传输 文件名、校验和、分片序号 文件二进制内容
POST /login HTTP/1.1 ← 起始行 + 头部
Content-Type: application/json
Content-Length: 43
{"username":"tom","password":"123"} ← 这就是 Payload
*/
/*
type StandardClaims struct {
Audience string `json:"aud,omitempty"` // 受众
ExpiresAt int64 `json:"exp,omitempty"` // 过期时间(Unix 秒)
Id string `json:"jti,omitempty"` // JWT ID
IssuedAt int64 `json:"iat,omitempty"` // 签发时间
Issuer string `json:"iss,omitempty"` // 签发者
NotBefore int64 `json:"nbf,omitempty"` // 在此时间之前无效
Subject string `json:"sub,omitempty"` // 主题
}