无需Redis和数据库,使用ScheduledExecutorService实现Java Token过期时间控制
一种可行的方法是使用Java的ScheduledExecutorService来定时清理过期的token。具体步骤如下:
-
在用户登录成功后,为其生成一个token,并将其存储在一个HashMap中,同时记录下该token的生成时间;
-
在每次用户请求接口时,先从请求头中获取token,然后在HashMap中查找该token是否存在;
-
如果该token不存在,或者已经过期,则返回登录失效的错误提示;否则,更新该token的最后访问时间,并返回正常的接口响应;
-
另外,还需要启动一个ScheduledExecutorService线程池,定时遍历HashMap中的所有token,将已经过期的token清除掉。
示例代码如下:
public class TokenManager {
// 存储token的HashMap
private static Map<String, Long> tokenMap = new ConcurrentHashMap<>();
// token的有效期(单位:秒)
private static final long TOKEN_EXPIRE_TIME = 3600;
static {
// 启动一个线程池,每分钟清理一次过期的token
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(TokenManager::clearExpiredTokens, 0, 1, TimeUnit.MINUTES);
}
/**
* 生成token并保存到HashMap中
*
* @param userId 用户ID
* @return 生成的token
*/
public static String generateToken(long userId) {
String token = UUID.randomUUID().toString();
long createTime = System.currentTimeMillis();
tokenMap.put(token, createTime);
return token;
}
/**
* 验证token是否有效
*
* @param token 用户请求中的token
* @return 验证结果
*/
public static boolean validateToken(String token) {
Long lastAccessTime = tokenMap.get(token);
if (lastAccessTime == null) {
return false;
}
if (System.currentTimeMillis() - lastAccessTime > TOKEN_EXPIRE_TIME * 1000) {
return false;
}
// 更新最后访问时间
tokenMap.put(token, System.currentTimeMillis());
return true;
}
/**
* 清理过期的token
*/
private static void clearExpiredTokens() {
long now = System.currentTimeMillis();
for (Iterator<Map.Entry<String, Long>> it = tokenMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Long> entry = it.next();
if (now - entry.getValue() > TOKEN_EXPIRE_TIME * 1000) {
it.remove();
}
}
}
}
在用户登录成功后,可以调用TokenManager.generateToken(userId)方法生成一个token,并将其返回给客户端。客户端在后续的请求中,需要在请求头中添加一个名为'token'的参数,值为上次登录时获取的token。在每次请求接口时,可以调用TokenManager.validateToken(token)方法验证token是否有效,如果返回false,则说明该token已经过期,需要重新登录获取新的token。同时,TokenManager会定时清理过期的token,以保证HashMap中存储的token不会无限增长,占用过多的内存。
原文地址: https://www.cveoy.top/t/topic/nZC7 著作权归作者所有。请勿转载和采集!