JWT中RefreshToken的应用场景及刷新token的具体实现思路

在JWT token中,refreshToken的作用主要是避免token过期时,前端用户突然退出登录产生不良体验。

试想,如果你正访问某基于jwt token机制的网站,该网站token过期时间是24小时,

你在23小时59分前已经登录过了,现在你访问某页面时,正好处于token过期时间24小时的临界点,

这时token突然过期,你上一秒看视频正起劲儿呢,下一秒就让你重新登录了,你说气不气?

这时候如果有一个refreshToken,虽然正式的token过期了,但前端却可以拿这个refreshToken来主动续期。

这样就解决了token过期导致用户上一秒还在登录,下一秒就突然退出登录的问题。


但是如何实现通过refreshToken刷新token呢?

  1. 首先,refreshToken有效时间一定要比token有效时间长至少才能不影响用户体验,具体要长多少得以实际需求为准,建议是24小时

  2. 前端每次访问后端都携带token,如果token失效则后端直接返回类似token失效请重新登录的报文。

  3. 前端第一次收到token失效的响应后,从本地存储拿refreshToken再去请求

  4. 后端一检测到refreshToken参数不为空,就去校验解析这个refreshToken

    1. 如果有效,后端就返回一个新的token及refreshToken给前端,前端收到后更新本地存储,同时拿这个新的token向后端发起第三次请求,然后成功获取资源

    2. 如果无效,则后端同样返回token失效,前端第二次收到失效的响应则跳转到登录页重新登录

这样就解决了以上场景的问题

 

 

### 如何生成 JWT TokenRefreshToken 为了实现 JWT TokenRefreshToken 的生成,通常会设计一个工具类来封装这些功能。此工具类应具备如下特性: - 提供方法用于生成 `access_token` 和 `refresh_token` - 支持从 JWT 中提取所需的信息 - 检查 JWT 是否已过期 #### 配置应用参数 在应用程序配置文件中定义必要的 JWT 参数是非常重要的。对于 Spring Boot 应用程序而言,在 `application.yml` 文件内指定密钥和两种令牌的有效期限[^3]。 ```yaml jwt: secret: your_secret_key access-token-expiration: 3600 # 即1小时 refresh-token-expiration: 604800 # 即7天 ``` #### 实现 JWT 工具类 下面是一个简单的 Java 版本的 JWT 工具类示例,它实现了上述提到的功能: ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.function.Function; public class JwtUtil { private String SECRET_KEY = "your_secret_key"; public String generateAccessToken(String username) { Map<String, Object> claims = new HashMap<>(); return createToken(claims, username, "access"); } public String generateRefreshToken(String username) { Map<String, Object> claims = new HashMap<>(); claims.put("type", "refresh"); return createToken(claims, username, "refresh"); } private String createToken(Map<String, Object> claims, String subject, String type) { long expirationTimeMillis; if ("access".equals(type)) { expirationTimeMillis = Long.parseLong(env.getProperty("jwt.access-token-expiration")) * 1000; } else { // assume it's a refresh token expirationTimeMillis = Long.parseLong(env.getProperty("jwt.refresh-token-expiration")) * 1000; } final Date createdDate = new Date(); final Date expirationDate = new Date(createdDate.getTime() + expirationTimeMillis); return Jwts.builder() .setClaims(claims) .setSubject(subject) .setIssuedAt(createdDate) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public Boolean isTokenExpired(String token) { final Date expiration = getExpirationDateFromToken(token); return expiration.before(new Date()); } private Claims extractAllClaims(String token) { return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody(); } private Date getExpirationDateFromToken(String token) { return getClaimFromToken(token, Claims::getExpiration); } private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) { final Claims claims = extractAllClaims(token); return claimsResolver.apply(claims); } } ``` 这段代码展示了如何通过给定的主题(通常是用户名)创建两个不同类型的令牌——访问令牌(`access_token`)和刷新令牌(`refresh_token`)。此外还提供了检查令牌是否已经到期的方法[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值