JWT0.12的令牌生成和配置
本文最后更新于 2024-07-08,文章内容可能已经过时。
JWT0.12的令牌生成和配置
1. jwt介绍
一个JWT由三个部分组成:JWT头、有效载荷、签名哈希。最后由这三者组合进行base64url编码得到JWT
典型的,一个JWT看起来如下图:该对象为一个很长的字符串,字符之间通过”.“分隔符分为三个子串。
组成:
第一部分:Header(头), 记录令牌类型、签名算法等。 例如:{“alg”:“HS256”,“type”:“JWT”}
第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{“id”:“1”,“username”:“Tom”}
第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。
本次配置:SpringBoot3.1.5 + JDK17 + MyBatisPlus3.5.3.1 + jwt0.12.3
2.依赖导入
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.12.3</version>
</dependency>
3.实现代码
/**
*desc jwt配置类: JSON WEB TOKEN,分别由:Header(头部)、Payload(负载)、Signature(签名)组成
* @author GrayPigeonHGH
* @since 2024年03月16日
*/
public class JwtHelper {
//设置解析令牌的密钥
//依赖jjwt0.9.1之后的版本对于密钥安全性要求更高(体现在secret密钥的长度要达到一定的位数)
private static SecretKey secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode("12345612qwwwwwwwwwwwwwwwwwwwwwwwwwwwww33333333333333333333333"));
//或者 SecretKey secretKey = Keys.hmacShaKeyFor(s.getBytes()); //s为一个字符串秘钥(长度大于256位)
private static long ttlMillis = 365 * 24 * 60 * 60 * 1000;
/**
* 生成token令牌(jwt)
* 使用Hs256算法
* @param claims 设置的信息
* @return
*/
public static String createToken(Map<String, Object> claims){
String token = Jwts.builder()
//设置签名使用的签名算法和签名使用的秘钥
.signWith(secretKey, Jwts.SIG.HS256)
.expiration(new Date(System.currentTimeMillis()+ttlMillis)) //设置token有效时长
.claims(claims) //设置自定义负载信息
.compact(); //设置过期时间
return token;
}
/**
* 先解析jwt
* 再从Token中获取负载中的Claims:getPayload();
* @param token token
* @return 负载
*/
private static Claims getPayload(String token)
{
return Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token)
.getPayload();
}
/**
* 从Token中获取用户名
* @param token token
* @return String
*/
public static String getUsername(String token){
try
{
String userName = (String) getPayload(token).get("userName");
return userName;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 从Token中获取用户ID
* @param token token
* @return Long
*/
public static Long getUserId(String token){
try
{
String userId = (String) getPayload(token).get("userId");
return Long.valueOf(userId);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 初始化负载内数据
* @param userName 用户名
* @return 负载集合
*/
private static Map<String,Object> initClaims(String userName, String userId){
Map<String, Object> claims = new HashMap<>();
//"iss" (Issuer): 代表 JWT 的签发者。在这个字段中填入一个字符串,表示该 JWT 是由谁签发的。例如,可以填入你的应用程序的名称或标识符。
claims.put("iss","jx");
//"sub" (Subject): 代表 JWT 的主题,即该 JWT 所面向的用户。可以是用户的唯一标识符或者其他相关信息。
claims.put("sub","hgh");
//"exp" (Expiration Time): 代表 JWT 的过期时间。通常以 UNIX 时间戳表示,表示在这个时间之后该 JWT 将会过期。建议设定一个未来的时间点以保证 JWT 的有效性,比如一个小时、一天、一个月后的时间。
claims.put("exp",""));
//"aud" (Audience): 代表 JWT 的接收者。这个字段可以填入该 JWT 预期的接收者,可以是单个用户、一组用户、或者某个服务。
claims.put("aud","internal use");
//"iat" (Issued At): 代表 JWT 的签发时间。同样使用 UNIX 时间戳表示。
claims.put("iat",new Date());
//"jti" (JWT ID): JWT 的唯一标识符。这个字段可以用来标识 JWT 的唯一性,避免重放攻击等问题。
claims.put("jti", UUID.randomUUID().toString());
//"nbf" (Not Before): 代表 JWT 的生效时间。在这个时间之前 JWT 不会生效,通常也是一个 UNIX 时间戳。我这里不填,没这个需求
claims.put("nbf", "");
claims.put("userId", userId); //自定义负载
claims.put("userName", userName); //自定义负载
return claims;
}
//测试
public static void main(String[] args) {
String token = JwtHelper.createToken(JwtHelper.initClaims("hgh", "2341513"));
String userName = JwtHelper.getUsername(token);
Long userId = JwtHelper.getUserId(token);
System.out.println(token);
System.out.println(userName);
System.out.println(userId);
}
}
参考自:https://blog.csdn.net/qq_45137726/article/details/135885870
https://blog.csdn.net/bigqiangwu/article/details/134694419?
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员Graypigeon
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果