赞
踩
一个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
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.12.3</version>
</dependency>
/** *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?
JWT官方:https://jwt.io/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。