当前位置: 首页 > news >正文

Access token(访问令牌:以JWT格式无状态存储)和Refresh token(刷新令牌:有状态存储于Redis/DB)区别与联系、Redis黑名单

文章目录

  • **1. Access Token**
    • **定义**
      • - **Access Token**(访问令牌)是短期有效的凭证,用于访问受保护的资源(如 API 接口、数据库等)。
      • - **特点**:
    • **作用**
      • - 直接用于访问资源,例如调用 API 接口时,客户端需在请求头中携带 `Authorization: Bearer <access_token>`。
  • **2. Refresh Token**
    • **定义**
      • - **Refresh Token**(刷新令牌)是长期有效的凭证,用于获取新的 Access Token。
      • - **特点**:
    • **作用**
      • - 在 Access Token 过期时,客户端使用 Refresh Token 向认证服务器请求新的 Access Token,避免用户频繁登录。
  • **3. 工作流程**
    • **初次登录**
      • 1. 用户提交用户名和密码。
      • 2. 认证服务器验证成功后,生成并返回:
      • 3. 客户端将两个 Token 存储在安全位置(如本地存储或 Cookie)。
    • **访问受保护资源**
      • 1. 客户端携带 Access Token 发送请求(如 `Authorization: Bearer <access_token>`)。
      • 2. 服务端验证 Access Token:
    • **刷新 Access Token**
      • 1. 客户端检测到 `401` 错误后,使用 Refresh Token 向认证服务器发起刷新请求。
      • 2. 认证服务器验证 Refresh Token:
      • 3. 客户端更新本地存储的 Token,并重新发送之前失败的请求。
    • **重新登录**
      • - 若 Refresh Token 也过期或无效,客户端需引导用户重新登录,获取新的 Access Token 和 Refresh Token。
  • **4. 安全性设计**
    • **Access Token 的安全性**
      • - **短时效**:减少被窃取后的影响范围。
      • - **加密传输**:通过 HTTPS 传输,防止中间人攻击。
      • - **权限最小化**:仅包含必要的权限,避免越权操作。
    • **Refresh Token 的安全性**
      • - **存储安全**:避免明文存储,可使用加密或服务器端存储(如 Redis)。
      • - **限制使用次数**:防止无限刷新(如每次刷新后生成新的 Refresh Token)。
      • - **绑定设备或会话**:与客户端 IP、设备指纹等绑定,增强安全性。
      • - **及时失效**:用户登出时主动使 Refresh Token 失效。
  • **5. 双 Token 机制的优势**
    • 1. **安全性**:
      • - Access Token 短时效,降低泄露风险。
      • - Refresh Token 仅在必要时使用,减少暴露机会。
    • 2. **用户体验**:
      • - 用户无需频繁登录,通过 Refresh Token 实现“无感刷新”。
    • 3. **灵活性**:
      • - 可根据业务需求调整 Access Token 和 Refresh Token 的有效期。
    • 4. **兼容性**:
      • - 支持 OAuth 2.0 协议,适用于 Web、移动端和第三方应用。
  • **6. 实际应用场景**
    • - **Web 应用**:用户登录后,Access Token 用于 API 调用,Refresh Token 用于后台自动续期。
    • - **移动应用**:长期保持登录状态,通过 Refresh Token 避免频繁输入密码。
    • - **第三方服务集成**:如微信开放平台,通过双 Token 机制管理用户授权和访问权限。
  • **7. 常见问题与解决方案**
    • **Q1: 如果 Refresh Token 被盗怎么办?**
      • - **解决方案**:
    • **Q2: 如何检测 Access Token 是否过期?**
      • - **解决方案**:
    • **Q3: 是否可以无限刷新 Access Token?**
      • - **解决方案**:
  • **8. 代码示例(简化版)**
    • **生成 Token(服务端)**
    • **刷新 Token(客户端)**
  • **总结**
    • - **Access Token** 是短期凭证,用于直接访问资源,需频繁刷新。
    • - **Refresh Token** 是长期凭证,用于安全获取新的 Access Token,减少用户登录频率。
    • - 双 Token 机制通过短时令牌和长时令牌的结合,在安全性和用户体验之间取得平衡,是现代身份认证的核心方案之一。
  • 补充:关于状态存储最佳实践
    • **1. Access Token 的存储:无状态 vs 有状态**
      • **推荐方案:无状态存储(如 JWT 自验证)**
      • **例外情况:有状态存储**
    • **2. Refresh Token 的存储:有状态存储**
      • **推荐方案:有状态存储(如 Redis 或数据库)**
    • **3. 最佳实践总结**
      • **具体建议**
    • **4. 示例代码(基于 Spring Security OAuth2)**
      • **Access Token(JWT 无状态)**
      • **Refresh Token(Redis 有状态)**
    • **5. 场景适配建议**
      • - **高安全性场景**(如金融系统):
      • - **高性能场景**(如内容 API):
    • **总结**
      • - **Access Token**:**无状态存储(JWT)** 是主流方案,兼顾性能和扩展性。
      • - **Refresh Token**:**有状态存储(Redis/DB)** 是必然选择,确保安全性和可控性。
      • - **混合方案**:通过 JWT + Redis 黑名单,平衡性能与安全性,适应大多数业务需求。

Access Token 和 Refresh Token 是现代身份认证和授权机制中的核心组件,主要用于在保障安全性的同时提升用户体验。以下是它们的原理及工作流程的详细解释:


1. Access Token

定义

- Access Token(访问令牌)是短期有效的凭证,用于访问受保护的资源(如 API 接口、数据库等)。

- 特点

  • 有效期短:通常为几分钟到几小时(如 15 分钟到 2 小时)。
  • 高频传输:每次请求受保护资源时都需要携带。
  • 包含用户信息:通常基于 JWT(JSON Web Token)格式,包含用户身份、权限等信息。
  • 过期后需重新获取:不能直接续期,需通过 Refresh Token 获取新的 Access Token。

作用

- 直接用于访问资源,例如调用 API 接口时,客户端需在请求头中携带 Authorization: Bearer <access_token>


2. Refresh Token

定义

- Refresh Token(刷新令牌)是长期有效的凭证,用于获取新的 Access Token。

- 特点

  • 有效期长:通常为几天到几个月(如 30 天)。
  • 低频传输:仅在 Access Token 过期时用于刷新,传输次数较少。
  • 不包含用户信息:仅用于身份验证,不直接用于访问资源。
  • 安全存储:需加密存储(如 HttpOnly Cookie 或服务器端数据库)。

作用

- 在 Access Token 过期时,客户端使用 Refresh Token 向认证服务器请求新的 Access Token,避免用户频繁登录。


3. 工作流程

初次登录

1. 用户提交用户名和密码。

2. 认证服务器验证成功后,生成并返回:

  • Access Token(短期)。
  • Refresh Token(长期)。

3. 客户端将两个 Token 存储在安全位置(如本地存储或 Cookie)。

访问受保护资源

1. 客户端携带 Access Token 发送请求(如 Authorization: Bearer <access_token>)。

2. 服务端验证 Access Token:

  • 有效:返回资源数据。
  • 过期:返回 401 Unauthorized 错误。

刷新 Access Token

1. 客户端检测到 401 错误后,使用 Refresh Token 向认证服务器发起刷新请求。

2. 认证服务器验证 Refresh Token:

  • 有效:生成新的 Access Token(可能同时生成新的 Refresh Token),并返回给客户端。
  • 无效:返回 401403,客户端需重新登录。

3. 客户端更新本地存储的 Token,并重新发送之前失败的请求。

重新登录

- 若 Refresh Token 也过期或无效,客户端需引导用户重新登录,获取新的 Access Token 和 Refresh Token。


4. 安全性设计

Access Token 的安全性

- 短时效:减少被窃取后的影响范围。

- 加密传输:通过 HTTPS 传输,防止中间人攻击。

- 权限最小化:仅包含必要的权限,避免越权操作。

Refresh Token 的安全性

- 存储安全:避免明文存储,可使用加密或服务器端存储(如 Redis)。

- 限制使用次数:防止无限刷新(如每次刷新后生成新的 Refresh Token)。

- 绑定设备或会话:与客户端 IP、设备指纹等绑定,增强安全性。

- 及时失效:用户登出时主动使 Refresh Token 失效。


5. 双 Token 机制的优势

1. 安全性

- Access Token 短时效,降低泄露风险。

- Refresh Token 仅在必要时使用,减少暴露机会。

2. 用户体验

- 用户无需频繁登录,通过 Refresh Token 实现“无感刷新”。

3. 灵活性

- 可根据业务需求调整 Access Token 和 Refresh Token 的有效期。

4. 兼容性

- 支持 OAuth 2.0 协议,适用于 Web、移动端和第三方应用。


6. 实际应用场景

- Web 应用:用户登录后,Access Token 用于 API 调用,Refresh Token 用于后台自动续期。

- 移动应用:长期保持登录状态,通过 Refresh Token 避免频繁输入密码。

- 第三方服务集成:如微信开放平台,通过双 Token 机制管理用户授权和访问权限。


7. 常见问题与解决方案

Q1: 如果 Refresh Token 被盗怎么办?

- 解决方案

  • 限制 Refresh Token 的使用次数,每次刷新后生成新的 Token。
  • 绑定用户设备或 IP 地址,异常行为时触发安全策略。
  • 提供“强制登出”功能,使所有关联 Token 失效。

Q2: 如何检测 Access Token 是否过期?

- 解决方案

  • 服务端返回 401 Unauthorized 错误时,客户端自动触发 Refresh Token 流程。
  • 客户端可主动检查 Token 剩余有效期(如提前 5 分钟刷新)。

Q3: 是否可以无限刷新 Access Token?

- 解决方案

  • 限制 Refresh Token 的总使用次数或最大有效期。
  • 每次刷新时生成新的 Refresh Token,旧的 Token 自动失效。

8. 代码示例(简化版)

生成 Token(服务端)

// 使用 JWT 生成 Access Token 和 Refresh Token
String accessToken = Jwts.builder().setSubject(userId).setExpiration(new Date(System.currentTimeMillis() + 15 * 60 * 1000)) // 15分钟.signWith(SignatureAlgorithm.HS256, "secretKey").compact();String refreshToken = Jwts.builder().setSubject(userId).setExpiration(new Date(System.currentTimeMillis() + 30 * 24 * 60 * 60 * 1000)) // 30天.signWith(SignatureAlgorithm.HS256, "secretKey").compact();

刷新 Token(客户端)

// 检测 401 错误后自动刷新
function refreshToken() {fetch('/api/auth/refresh', {method: 'POST',body: JSON.stringify({ refreshToken: storedRefreshToken })}).then(response => response.json()).then(data => {localStorage.setItem('accessToken', data.accessToken);localStorage.setItem('refreshToken', data.refreshToken);retryOriginalRequest(); // 重新发送之前的请求}).catch(() => {// 刷新失败,跳转登录页});
}

总结

- Access Token 是短期凭证,用于直接访问资源,需频繁刷新。

- Refresh Token 是长期凭证,用于安全获取新的 Access Token,减少用户登录频率。

- 双 Token 机制通过短时令牌和长时令牌的结合,在安全性和用户体验之间取得平衡,是现代身份认证的核心方案之一。

补充:关于状态存储最佳实践

在 OAuth2 认证体系中,Access TokenRefresh Token 的存储策略需根据其生命周期、安全性和性能需求进行区分。以下是常见的最佳实践和建议:


1. Access Token 的存储:无状态 vs 有状态

推荐方案:无状态存储(如 JWT 自验证)

  • 原因
    • Access Token 是短期有效的(通常几分钟到几小时),适合通过 JWT(JSON Web Token) 实现自包含的无状态验证。
    • 无需频繁查询数据库或缓存,减少服务器资源消耗,提升性能。
    • 适合分布式系统,因为每个服务节点无需共享存储即可独立验证 Token。
  • 实现方式
    • 使用 JWT 格式生成 Access Token,包含用户身份、权限、过期时间等信息。
    • 服务端通过签名验证 Token 的合法性(无需存储)。
  • 适用场景
    • 高并发、低延迟的 API 服务。
    • 微服务架构中,多个服务节点无需共享 Token 状态。

例外情况:有状态存储

  • 如果 Access Token 需要主动吊销(如用户登出),可结合 黑名单机制 实现有状态存储:
    • 将被吊销的 Token 存入 Redis 黑名单(设置短过期时间)。
    • 验证 Token 时同时检查黑名单。

2. Refresh Token 的存储:有状态存储

推荐方案:有状态存储(如 Redis 或数据库)

  • 原因
    • Refresh Token 是长期有效的(通常几天到几个月),需频繁更新、刷新和主动吊销。
    • 安全性要求高,需记录 Token 的状态(是否有效、绑定的用户、设备信息等)。
    • 需支持主动失效(如用户登出或安全事件)。
  • 实现方式
    • 将 Refresh Token 存储在 Redis 或数据库中,键值格式示例:
      key: refresh_token:{token_value}
      value: {user_id, issued_at, expires_at, client_id, ...}
      
    • 设置合理的过期时间(与 Refresh Token 有效期一致)。
    • 登出时删除或标记为失效。
  • 安全增强措施
    • 绑定设备或 IP:将 Refresh Token 与用户设备指纹、IP 地址绑定,防止跨设备滥用。
    • 限制刷新次数:每次刷新后生成新的 Refresh Token,旧 Token 自动失效。
    • 加密存储:对 Token 值进行加密或哈希处理,避免明文存储。

3. 最佳实践总结

Token 类型存储方式理由
Access Token无状态(JWT)短期有效,自验证,提升性能;适合分布式系统。
Refresh Token有状态(Redis/DB)长期有效,需管理状态(刷新、吊销);需绑定用户和设备信息。

具体建议

  1. Access Token

    • 使用 JWT 格式,包含用户身份、权限、过期时间(exp)。
    • 通过 HTTPS 传输,防止中间人攻击。
    • 设置较短的过期时间(如 15 分钟)。
  2. Refresh Token

    • 存储在 Redis 或数据库中,设置与 Token 有效期一致的过期时间。
    • 每次刷新时生成新的 Refresh Token,旧 Token 失效。
    • 登出时主动删除 Refresh Token。
  3. 混合方案

    • Access Token 无状态:通过 JWT 自验证。
    • Refresh Token 有状态:通过 Redis/DB 管理状态。
    • 黑名单机制:对被吊销的 Access Token 使用 Redis 黑名单(短过期时间)。
  4. 安全性增强

    • 绑定设备/IP:将 Refresh Token 与用户设备指纹、IP 地址绑定。
    • 加密签名:JWT 使用强签名算法(如 HS256 或 RS256)。
    • 限制作用域:Access Token 仅包含必要的权限(最小化原则)。

4. 示例代码(基于 Spring Security OAuth2)

Access Token(JWT 无状态)

// 生成 JWT Access Token
String accessToken = Jwts.builder().setSubject(userId).claim("roles", userRoles) // 权限信息.setExpiration(new Date(System.currentTimeMillis() + 15 * 60 * 1000)) // 15分钟.signWith(SignatureAlgorithm.HS256, "your-secret-key").compact();

Refresh Token(Redis 有状态)

// 存储 Refresh Token 到 Redis
redisTemplate.opsForValue().set("refresh_token:" + refreshTokenValue, userId, Duration.ofDays(30) // 30天过期
);// 验证并刷新 Token
String storedUserId = redisTemplate.opsForValue().get("refresh_token:" + refreshTokenValue);
if (storedUserId != null) {// 生成新的 Access Token 和 Refresh TokenString newAccessToken = generateJwtAccessToken(storedUserId);String newRefreshToken = generateRefreshToken();redisTemplate.opsForValue().set("refresh_token:" + newRefreshToken, storedUserId, Duration.ofDays(30));return newAccessToken + ":" + newRefreshToken;
} else {throw new InvalidTokenException("Invalid refresh token");
}

5. 场景适配建议

- 高安全性场景(如金融系统):

  • 使用 Redis 存储 Refresh Token,并绑定设备/IP。
  • Access Token 使用 JWT,但通过黑名单机制管理过期。

- 高性能场景(如内容 API):

  • Access Token 完全无状态(JWT),Refresh Token 存储在 Redis。
  • 设置较短的 Refresh Token 刷新频率。
  • 分布式系统
    • 使用 Redis 集群存储 Refresh Token,确保状态一致性。
    • Access Token 通过 JWT 自验证,无需跨节点通信。

总结

- Access Token无状态存储(JWT) 是主流方案,兼顾性能和扩展性。

- Refresh Token有状态存储(Redis/DB) 是必然选择,确保安全性和可控性。

- 混合方案:通过 JWT + Redis 黑名单,平衡性能与安全性,适应大多数业务需求。

http://www.dtcms.com/a/355621.html

相关文章:

  • C#-mqtt通讯,服务端和客户端,以及esp32-mqtt
  • 第二十节:3D文本渲染 - 字体几何体生成与特效
  • 神经网络 | 基于matlab的LSTM详解
  • 3D高斯溅射实现医疗影像内部场景渲染
  • 【论文阅读】Object Detection in Adverse Weather for Autonomous Driving through Data Merging and YOLOv8
  • ConceptGraphs: Open-Vocabulary 3D Scene Graphs for Perception and Planning
  • 第八章:《性能优化技巧》——深入讲解预分配容量、移动语义、避免频繁拼接等优化策略,以及C++17的`string_view`如何减少拷贝开
  • 三电平逆变器SVPWM控制(无解耦功能)与谐波分析
  • gpt-5生成圆柱blockmesh脚本
  • UDS NRC24
  • 修改win11任务栏时间字体和小图标颜色
  • Graphpad Prism Mac医学绘图工具
  • GraphRAG技术深度解析:重新定义智能问答的未来
  • 数据结构初阶:详解顺序表OJ题
  • CUDA 矩阵分块乘法
  • Rust Web开发指南 第六章(动态网页模板技术-MiniJinja速成教程)
  • Docker 核心技术:Union File System
  • 知微集:梯度下降详解
  • 编写TreeMap自定义排序的插曲
  • 信号量使用流程
  • 多媒体内容智能检索技术进展
  • [特殊字符] ​​MySQL性能参数查询总结​
  • 146-延长无线传感器网络生命周期的睡眠调度机制的混合元启发式优化方法!
  • [RK3576][Android14] Android->添加以太网MAC地址选项
  • Spring Boot 实战:接入 DeepSeek API 实现问卷文本优化
  • FFmpeg 实战:从零开始写一个简易视频播放器
  • 视频层和叠加层
  • 数据结构:冒泡排序 (Bubble Sort)
  • Android14 USB子系统的启动以及动态切换相关的init.usb.rc详解
  • mysql主从复制GTID模式