Java 实现 Token 失效功能

引言

在开发应用程序时,我们经常需要使用Token来进行用户认证和授权。Token是一种代表用户身份的字符串,通常在用户登录后由服务器颁发,并在每次请求时进行验证。然而,有时候我们需要让Token在一定时间后失效,以增加系统的安全性。本文将介绍如何使用Java实现Token失效功能。

流程概述

下面是实现Token失效的流程图:

journey
    title Token失效流程
    section 用户登录
    用户登录->生成Token: 用户登录成功,生成Token
    生成Token->返回Token: 向客户端返回Token

    section Token验证
    返回Token->解析Token: 客户端解析Token
    解析Token->验证Token: 验证Token有效性
    验证Token->返回结果: 返回验证结果

    section Token失效
    返回结果->检查Token过期: 如果Token未失效
    检查Token过期->返回结果: 返回验证结果
    返回结果->更新Token过期时间: 更新Token过期时间
    更新Token过期时间->返回结果: 返回验证结果
    返回结果->Token失效: 如果Token已失效
    Token失效->返回结果: 返回失效结果

具体步骤及代码实现

下面是实现Token失效功能的具体步骤以及相应的代码实现:

  1. 生成Token

在用户登录成功后,需要生成Token并返回给客户端。

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class TokenUtil {
    private static final String SECRET_KEY = "your-secret-key";
    private static final long EXPIRATION_TIME = 3600000; // 1 hour

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }
}
  1. 解析Token和验证Token有效性

客户端在每次请求中需要解析Token,并验证Token的有效性。

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

public class TokenUtil {
    // ...

    public static boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static String getUsernameFromToken(String token) {
        Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
        return claims.getSubject();
    }
}
  1. 检查Token过期和更新Token过期时间

在验证Token有效性后,需要检查Token是否已过期,并根据需要更新Token的过期时间。

import io.jsonwebtoken.Jwts;

public class TokenUtil {
    // ...

    public static boolean isTokenExpired(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration().before(new Date());
    }

    public static String refreshExpirationTime(String token) {
        Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }
}
  1. Token失效处理

如果Token已过期,则将Token标记为失效。

import java.util.HashSet;
import java.util.Set;

public class TokenCache {
    private static final Set<String> expiredTokens = new HashSet<>();

    public static void invalidateToken(String token) {
        expiredTokens.add(token);
    }

    public static boolean isTokenInvalid(String token) {
        return expiredTokens.contains(token);
    }
}
  1. 整合所有步骤

最后,将上述步骤整合起来,实现完整的Token失效功能。

public class TokenUtil {
    // ...

    public static boolean validateAndRefreshToken(String token) {
        if (validateToken(token)) {
            if (isTokenExpired(token)) {
                invalidateToken(token);
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }
}

总结

通过上述步骤,我们可以实现Java中的Token失效功能。在用户登录成功后,服务器生成Token并返回给客户