hutool-JWT
package com.litongjava.tio.boot.hello.AController;
import cn.hutool.jwt.JWTUtil;
import com.litongjava.tio.http.common.HeaderName;
import com.litongjava.tio.http.common.HeaderValue;
import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import com.litongjava.tio.utils.resp.RespBodyVo;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* token永不过期
*/
@AController
@RequestPath("/auth")
public class AuthController {
// 使用HmacSHA256签名算法的密钥
byte[] key = "litongjava".getBytes();
// 用于存储tokens的Map
private static Map<String, String> tokenStore = new HashMap<>();
@RequestPath("/login")
public HttpResponse login(HttpRequest request, String username, String password) {
if (isValidUser(username, password)) {
// 生成JWT token
String accessToken = createJWTToken(username, key);
// 将token存储到Map中
tokenStore.put(username, accessToken);
// 创建HttpResponse,并添加token作为头部
HeaderName headerName = HeaderName.from("Authorization");
HeaderValue headerValue = HeaderValue.from("Bearer " + accessToken);
HttpResponse httpResponse = Resps.json(request, RespBodyVo.ok());
httpResponse.addHeader(headerName, headerValue);
return httpResponse;
} else {
return Resps.json(request, RespBodyVo.fail("Invalid username or password"));
}
}
@RequestPath("/verifyToken")
public RespBodyVo verifyToken(String token) {
// 验证token是否有效
if (isValidToken(token)) {
return RespBodyVo.ok();
} else {
return RespBodyVo.fail("Token is invalid or expired");
}
}
private boolean isValidUser(String username, String password) {
// 在这里实现您的用户验证逻辑
// 暂时返回true模拟验证成功
return true;
}
public static String createJWTToken(String username, byte[] key) {
// 载荷,可根据需要添加更多数据
Map<String, Object> payload = new HashMap<>();
payload.put("username", username);
// 设置过期时间,例如1小时后
long expirationMillis = System.currentTimeMillis() + 3600000; // 1小时 = 3600000毫秒
Date expiration = new Date(expirationMillis);
payload.put("exp", expiration.getTime() / 1000); // JWT通常使用秒为单位的时间戳
// 生成JWT token
return JWTUtil.createToken(payload, key);
}
private boolean isValidToken(String token) {
// 使用相同的密钥验证token
return JWTUtil.verify(token, key);
}
}
代码展示了一个用于身份验证和令牌管理的 AuthController
类,它是使用 tio-boot 框架编写的。这个类提供了用户登录和验证令牌的功能。下面是对代码的关键点的解释:
类定义和成员变量:
- 类被注解为
@RequestPath("/auth")
,这意味着它处理以/auth
开头的 HTTP 请求路径。 key
是用于 JWT 签名的密钥,这里是一个硬编码的字符串"litongjava"
。在实际应用中,这个密钥应该是安全生成和存储的。tokenStore
是一个用于存储生成的令牌的静态映射(Map)。
- 类被注解为
login
方法:- 当用户尝试登录时,此方法被调用。
- 它首先调用
isValidUser
方法来验证用户名和密码。 - 如果验证成功,它调用
createJWTToken
方法生成 JWT 令牌。 - 然后,生成的令牌被存储在
tokenStore
中,并以Authorization
头的形式添加到响应中。 - 最后,方法返回一个
HttpResponse
对象,该对象包含 JSON 格式的响应。
verifyToken
方法:- 此方法用于验证传入的令牌是否有效。
- 它调用
isValidToken
方法来检查令牌。 - 根据令牌的有效性,它返回一个包含相应消息的
RespBodyVo
对象。
createJWTToken
方法:- 这是一个静态辅助方法,用于生成带有用户信息和过期时间的 JWT 令牌。
- 它将用户名作为载荷的一部分,并计算一个小时后的时间作为令牌的过期时间。
- 这个方法使用
JWTUtil.createToken
方法生成令牌。
isValidToken
方法:- 用于验证给定令牌的有效性。
- 它使用相同的密钥
key
来验证令牌。
安全性和实用性的考虑:
- 密钥应该安全生成和存储,不应硬编码在代码中。
- 在生产环境中,令牌应该有一个合理的过期时间,并且应该提供令牌刷新的机制。
- 用户验证逻辑(
isValidUser
方法)应该实现实际的验证过程,例如检查数据库中的用户凭据。 - 令牌存储(
tokenStore
)应考虑使用更安全和可扩展的存储解决方案,如数据库或缓存系统。在内存中存储令牌可能不适合大规模或生产环境。