java jwt过期刷新
时间: 2025-01-10 07:42:35 浏览: 77
### Java 中 JWT 过期后的令牌刷新机制
在构建基于 Spring Boot 和 Spring Security 的应用程序时,处理 JWT (JSON Web Token) 的过期以及实现自动刷新是一个常见的需求。为了确保安全性和用户体验,在设计刷新令牌逻辑时应考虑以下几个方面:
#### 1. 刷新令牌的设计原则
刷新令牌通常具有较长的有效期限,并用于获取新的访问令牌而不必重新登录。这不仅提高了用户的便利性也增强了系统的安全性。
- **存储方式**: 刷新令牌应该被安全地保存于服务器端数据库或其他持久化层中,而不是仅仅依赖客户端缓存。
- **验证流程**: 当接收到带有旧的或即将到期的访问令牌请求时,服务端会检查是否存在有效的对应刷新令牌来签发一个新的访问令牌[^1]。
#### 2. 实现步骤概述
以下是关于如何在 Java 应用程序中实现这一功能的具体方法:
##### 创建 RefreshTokenService 类
此服务负责管理所有与刷新令牌有关的操作,比如创建、验证和删除等操作。
```java
@Service
public class RefreshTokenService {
@Autowired
private RefreshTokenRepository refreshTokenRepository;
public Optional<RefreshToken> findByToken(String token){
return refreshTokenRepository.findByToken(token);
}
public RefreshToken createRefreshToken(User user){
RefreshToken refreshToken = new RefreshToken();
refreshToken.setUser(user);
refreshToken.setExpiryDate(Instant.now().plusMillis(jwtProperties.getRefreshExpirationMs()));
// Generate a random UUID as the refresh token value.
String uuid = java.util.UUID.randomUUID().toString();
refreshToken.setToken(uuid);
return refreshTokenRepository.save(refreshToken);
}
}
```
##### 修改 AuthenticationFilter
当检测到传入的 JWT 已经过期时,则查找相应的刷新令牌来进行验证;如果有效则返回新生成的一对 Access-Token 及其对应的 Refresh-Token 给前端应用。
```java
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult)
throws IOException {
UserPrincipal principal = (UserPrincipal)authResult.getPrincipal();
// Check if current access-token is expired and there's an associated valid refresh-token available.
boolean accessTokenExpired = jwtProvider.isTokenExpired(principal.getUsername());
if (!accessTokenExpired && !jwtProvider.hasValidRefreshToken(principal.getUsername())) {
Map<String,Object> claims = new HashMap<>();
claims.put("username",principal.getUsername());
// Create new pair of tokens here...
String newAccessToken = generateNewAccessToken(claims);
String newRefreshToken = refreshTokenService.createRefreshToken(principal.getUser()).getToken();
// Send back both tokens to client side via HTTP header or body content.
sendTokensBackToClient(response,newAccessToken ,newRefreshToken );
} else{
super.successfulAuthentication(request,response,chain,authResult);
}
}
```
##### 更新 JwtUtils 或者类似的工具类
提供必要的辅助函数用来解析载荷(payload),判断token是否已失效等功能。
```java
@Component
public class JwtUtils {
...
/**
* Checks whether given username has any non-expired refresh token stored on server-side database.
*/
public boolean hasValidRefreshToken(String username){
List<RefreshToken> list = refreshTokenService.findAllByUsername(username);
for (RefreshToken rt :list ) {
if(!rt.isExpired()){
return true;
}
}
return false;
}
...
}
```
通过上述代码片段可以了解到整个过程是如何运作的:每当成功完成身份认证之后都会去检查当前使用的access_token 是否已经过了有效期;如果是的话就尝试利用存在的refresh_token 来换取一对全新的tokens 并发送给客户端继续维持会话状态。
阅读全文
相关推荐


















