Access Token + Refresh Token 双令牌机制设计
用途 :用于访问受保护的 API 资源
特点 :
短期有效(建议:15分钟 - 2小时)
包含用户基本信息(user_id, username)
每次 API 请求都需要携带
过期后需要刷新
用途 :用于刷新过期的 Access Token
特点 :
长期有效(建议:7天 - 30天)
不包含用户信息,只包含 token_id
存储在服务端(Redis/数据库),可撤销
仅用于刷新接口,不能直接访问 API
1. 用户提交用户名和密码
POST /api/v1/users/login
{
"username": "user123",
"password": "password123"
}
2. 服务端验证用户信息
- 验证用户名和密码
- 检查用户状态(是否激活)
3. 生成双令牌
- 生成 Access Token(短期,如 2 小时)
- 生成 Refresh Token(长期,如 7 天)
- 将 Refresh Token 存储到 Redis/数据库
4. 返回令牌给客户端
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 7200, // Access Token 过期时间(秒)
"token_type": "Bearer",
"user": {
"id": 1,
"username": "user123",
"email": "user@example.com"
}
}
}
1. 客户端携带 Access Token 访问 API
GET /api/v1/users/profile
Authorization: Bearer {access_token}
2. 服务端验证 Access Token
- 解析 JWT token
- 验证签名和过期时间
- 提取用户信息
3. 返回 API 响应
- Token 有效:返回请求的数据
- Token 过期:返回 401,提示使用 Refresh Token 刷新
1. Access Token 过期,客户端使用 Refresh Token 刷新
POST /api/v1/auth/refresh
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
2. 服务端验证 Refresh Token
- 验证 Refresh Token 签名和过期时间
- 检查 Refresh Token 是否在 Redis/数据库中(是否被撤销)
- 验证用户状态(是否仍然有效)
3. 生成新的 Access Token
- 生成新的 Access Token
- 可选择是否刷新 Refresh Token(旋转策略)
4. 返回新的 Access Token
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...", // 可选,如果使用旋转策略
"expires_in": 7200
}
}
1. 客户端请求登出
POST /api/v1/auth/logout
Authorization: Bearer {access_token}
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
2. 服务端撤销 Refresh Token
- 从 Redis/数据库中删除 Refresh Token
- Access Token 无需处理(短期,自然过期)
3. 返回成功响应
{
"code": 0,
"message": "success"
}
Access Token :不存储,使用 JWT 自包含特性
Refresh Token :存储在 Redis,key 格式:refresh_token:{token_id}
存储内容:{"user_id": 1, "username": "user123", "expires_at": 1234567890}
TTL:与 Refresh Token 过期时间一致
创建 refresh_tokens 表
存储 Refresh Token 信息,支持查询和撤销
Refresh Token 刷新时,返回新的 Access Token
Refresh Token 保持不变,直到过期
Refresh Token 刷新时,同时生成新的 Access Token 和 Refresh Token
旧的 Refresh Token 立即失效
提高安全性,防止 Refresh Token 被盗用
主动撤销 :用户登出时删除 Refresh Token
被动撤销 :用户修改密码、账户被禁用时,删除所有 Refresh Token
批量撤销 :支持撤销用户的所有 Refresh Token
使用 HTTPS 传输
短期有效,减少泄露风险
不存储敏感信息
支持黑名单机制(可选,需要存储)
存储在服务端,可撤销
长期有效,但可以主动撤销
使用不同的密钥签名
限制使用频率(防止暴力破解)
使用 HTTPS
设置合理的过期时间
支持 Token 撤销
记录 Token 使用日志(可选)
POST /api/v1/users/login
Request:
{
"username": "string",
"password": "string"
}
Response:
{
"code": 0,
"message": "success",
"data": {
"access_token": "string",
"refresh_token": "string",
"expires_in": 7200,
"token_type": "Bearer",
"user": {...}
}
}
POST /api/v1/auth/refresh
Request:
{
"refresh_token": "string"
}
Response:
{
"code": 0,
"message": "success",
"data": {
"access_token": "string",
"refresh_token": "string", // 如果使用旋转策略
"expires_in": 7200
}
}
POST /api/v1/auth/logout
Headers:
Authorization: Bearer {access_token}
Request:
{
"refresh_token": "string"
}
Response:
{
"code": 0,
"message": "success"
}
JWT_ACCESS_SECRET: Access Token 签名密钥
JWT_ACCESS_EXPIRE: Access Token 过期时间(秒),建议 7200(2小时)
JWT_REFRESH_SECRET: Refresh Token 签名密钥(与 Access Token 不同)
JWT_REFRESH_EXPIRE: Refresh Token 过期时间(秒),建议 604800(7天)
REFRESH_TOKEN_PREFIX: Redis key 前缀,如 refresh_token:
REFRESH_TOKEN_TTL: Redis 存储 TTL,与 Refresh Token 过期时间一致
401 Unauthorized: Token 缺失、无效或过期
错误响应:
{
"code" : 401 ,
"message" : " Token expired" ,
"data" : {
"error" : " token_expired" ,
"refresh_url" : " /api/v1/auth/refresh"
}
}
401 Unauthorized: Refresh Token 无效、过期或已撤销
错误响应:
{
"code" : 401 ,
"message" : " Refresh token invalid or expired" ,
"data" : {
"error" : " refresh_token_invalid"
}
}
Access Token:存储在内存或 sessionStorage(前端)
Refresh Token:存储在 httpOnly cookie 或 localStorage(根据安全需求)
检测到 Access Token 过期(401 响应)
自动调用刷新接口
更新 Access Token
重试原始请求
Refresh Token 过期:跳转到登录页
网络错误:重试机制
并发刷新:防止多个请求同时刷新
扩展 JWT 工具 :支持生成和验证两种类型的 Token
创建 Refresh Token 存储 :Redis 或数据库
修改登录接口 :返回双令牌
创建刷新接口 :/api/v1/auth/refresh
创建登出接口 :/api/v1/auth/logout
更新认证中间件 :支持 Access Token 验证
添加配置项 :Token 相关配置
测试 :完整流程测试
Token 黑名单 :支持主动撤销 Access Token
设备管理 :支持多设备登录,分别管理 Refresh Token
Token 使用日志 :记录 Token 使用情况
IP 绑定 :Refresh Token 绑定 IP,提高安全性
频率限制 :限制刷新频率,防止滥用