C#如何实现JWT刷新Token Refresh Token机制实现方法

JWT刷新Token机制的核心是用长期有效的Refresh Token换取短期Access Token,实现免频繁登录与安全提升;需分离两者生命周期、安全存储Refresh Token(如Redis)、提供可靠刷新接口,并强化吊销与风控策略。

JWT刷新Token(Refresh Token)机制的核心是:用一个长期有效的Refresh Token换取新的短期Access Token,避免用户频繁登录,同时提升安全性。C#中实现的关键在于分离两种Token的生命周期、存储Refresh Token的安全方式,以及提供可靠的刷新接口。

Access Token与Refresh Token职责分离

Access Token用于每次API请求的身份校验,有效期短(如15–30分钟),不存数据库;Refresh Token用于获取新Access Token,有效期长(如7天),必须安全持久化(如Redis或加密后存数据库)。

  • Access Token只含必要声明(如subexprole),不存敏感信息
  • Refresh Token建议带唯一标识(jti)、绑定用户ID、设备指纹或IP(可选),便于后续吊销
  • 生成时使用不同密钥或不同签名算法(如Access用HS256,Refresh用RS256+私钥签名)更佳

服务端生成与验证逻辑(.NET 6/7/8)

以ASP.NET Core为例,在登录成功后同时签发两个Token:

  • Microsoft.IdentityModel.TokensSystem.IdentityModel.Tokens.Jwt生成JWT
  • Access Token设置短Expires(如DateTime.UtcNow.AddMinutes(20)
  • Refresh Token用随机安全字符串生成(RandomNumberGenerator),加密后存入Redis(键为refresh:{userId}:{jti},过期时间设为7天)
  • 响应体返回{ accessToken: "...", refreshToken: "..." },Refresh Token通过HttpOnly Cookie返回更安全(避免JS读取)

刷新接口(/api/auth/refresh)实现要点

该接口需校验Refresh Token有效性,并签发新Access Token:

  • 从Cookie或请求Body中提取Refresh Token
  • 解码并验证签名、未过期、且jti在Redis中存在(查refresh:{userId}:{jti}
  • 若验证通过,删除旧Refresh Token(防重放),生成新Access Token + 新Refresh Token
  • 将新Refresh Token再次存入Redis(同上键名,新jti),返回新Access Token
  • 若失败(如Token不存在、已被撤销、用户已禁用),返回401并清空客户端Refresh Token

安全增强建议

仅基础刷新不够,还需防范常见风险:

  • 每次刷新后更新Refresh Token(即“滚动刷新”),旧Token立即失效
  • 记录Refresh Token使用时间与IP,异常频次(如1小时内多次刷新)触发风控
  • 用户登出时主动删除Redis中所有该用户的Refresh Token(可用Redis前缀扫描+批量删除)
  • 敏感操作(如改密码、删账号)强制使全部Refresh Token失效
  • 前端在收到401且错误码为token_expired时自动调用刷新;失败则跳转登录页

基本上就这些。核心不是“怎么生成JWT”,而是“如何安全地管理Refresh Token的生命周期”。只要把存储、验证、吊销三个环节做扎实,机制就稳了。