Java JWT Token 过期刷新指南

在现代Web应用中,使用JSON Web Tokens (JWT) 进行用户身份验证和授权是一个常见的做法。一个重要的方面是如何处理JWT的过期问题,以确保安全性同时提升用户体验。本文将详细介绍如何在Java中实现JWT Token的过期刷新机制。

流程概述

下面是实现JWT Token过期刷新所需的步骤:

步骤 描述
1 用户登录并生成JWT Token
2 服务端验证Token并返回用户信息
3 客户端请求受保护的资源,并携带Token
4 服务端验证Token,如果Token过期则返回403状态
5 客户端检测到Token过期请求刷新Token
6 服务端验证刷新Token并发放新Token
7 客户端保存新Token并重试请求

详细步骤

下面将详细解释每一步所需的代码和注释。

1. 用户登录并生成JWT Token

在用户成功登录后,我们需要生成一个JWT Token。可以使用io.jsonwebtoken库来处理JWT。

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {
    private String secretKey = "your_secret_key"; // 秘钥
    private long validityInMilliseconds = 3600000; // 1小时有效期

    // 生成JWT Token
    public String generateToken(String username) {
        Date now = new Date();
        Date validity = new Date(now.getTime() + validityInMilliseconds);

        return Jwts.builder()
                .setSubject(username) // 用户名作为主题
                .setIssuedAt(now) // 签发时间
                .setExpiration(validity) // 过期时间
                .signWith(SignatureAlgorithm.HS256, secretKey) // 使用HS256算法进行签名
                .compact();
    }
}

2. 服务端验证Token并返回用户信息

在用户请求受保护资源时,服务端需要验证Token。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;

public class JwtUtil {
    // 验证JWT并获取用户名
    public String validateTokenAndGetUsername(String token) {
        Jws<Claims> claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token);
        return claims.getBody().getSubject(); // 返回用户名
    }
}

3. 客户端请求受保护的资源并携带Token

客户端在每个请求中需要带上JWT Token,通常是放在HTTP头部:

Authorization: Bearer {token}

4. 服务端验证Token,如果Token过期则返回403状态

服务端在处理请求时需要验证Token,若Token过期,则返回403。

import io.jsonwebtoken.ExpiredJwtException;

public void yourProtectedMethod(String token) {
    try {
        String username = jwtUtil.validateTokenAndGetUsername(token);
        // 处理业务逻辑
    } catch (ExpiredJwtException e) {
        // 返回403状态
        throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Token has expired");
    }
}

5. 客户端检测到Token过期请求刷新Token

客户端需要创建一个方法来处理Token的刷新。

// 假设有一个方法可以获取刷新Token 
public void handleTokenExpiry() {
    // 请求新的Token
    String newToken = requestNewToken(refreshToken); // refreshToken是已经存储的刷新Token
    // 保存新Token
    saveToken(newToken);
}

6. 服务端验证刷新Token并发放新Token

刷新Token的验证与JWT Token类似,但它的有效性通常更长。

public class RefreshTokenUtil {
    private long refreshTokenValidityInMilliseconds = 2592000000L; // 30天有效期

    public String generateRefreshToken(String username) {
        Date now = new Date();
        Date validity = new Date(now.getTime() + refreshTokenValidityInMilliseconds);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(validity)
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    // 验证刷新Token
    public boolean validateRefreshToken(String refreshToken) {
        // 验证逻辑(同上)
        return true;
    }
}

7. 客户端保存新Token并重试请求

客户端在获取到新Token后,需要将其保存,并重试之前的请求。

public void retryRequest(String apiUrl, String newToken) {
    // 重新发起请求,带上新的Token
    // 发起请求逻辑
}

序列图

以下是整个流程的序列图,使用Mermaid语法表示:

sequenceDiagram
    participant User
    participant Server
    participant Client

    User->>Client: Login request
    Client->>Server: Validate user and generate JWT
    Server-->>Client: Return JWT
    Client->>Server: Request resource with JWT
    Server->>Server: Verify JWT
    alt if JWT expired
        Server-->>Client: 403 Token expired
        Client->>Server: Request refresh token
        Server->>Server: Validate refresh token
        Server-->>Client: Return new JWT
        Client->>Server: Retry resource request with new JWT
    else
        Server-->>Client: Return resource
    end

甘特图

以下是实现每个步骤的甘特图:

gantt
    title JWT Token 过期刷新过程
    dateFormat  YYYY-MM-DD
    section User Login
    Login and generate JWT :a1, 2023-10-01, 2d
    section Resource Access
    Request resource :after a1  , 2023-10-03, 4d
    section Token Validation
    Validate JWT :a2, 2023-10-03, 1d
    Validate refresh token :after a2  , 2023-10-04, 1d
    Generate new JWT :after a2  , 2023-10-05, 1d

总结

通过以上的步骤,我们成功地实现了Java中的JWT Token过期刷新机制。这样一来,用户在Token过期后,只需通过刷新Token的方式即可获取新的Token,从而保证了他们的使用体验和安全性。希望这篇文章能够帮助你理解JWT及其过期处理机制,为你的项目积累更多的经验。如果你还有任何问题或者想要讨论的内容,请随时与我联系!