JWT0.12的令牌生成和配置

JWT0.12.3的令牌生成和配置

1. jwt介绍

一个JWT由三个部分组成:JWT头、有效载荷、签名哈希。最后由这三者组合进行base64url编码得到JWT

典型的,一个JWT看起来如下图:该对象为一个很长的字符串,字符之间通过"."分隔符分为三个子串。

img

组成:

第一部分: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?

JWT官方:https://jwt.io/

### JWT令牌生成 为了生成JWT令牌,可以采用多种方式。一种常见的方式是利用Java中的`Jwts.builder()`方法构建并创建带有签名的JSON Web Token (JWT)[^1]。 ```java import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @Test public void createJwt() { String secretKey = "chengxuyuanchengxuyuanchengxuyuanchengxuyuanchengxuyuan"; String compactJws = Jwts.builder() .setSubject("KBLL") .claim("id", 1) .signWith(SignatureAlgorithm.HS256, secretKey.getBytes()) .compact(); System.out.println(compactJws); } ``` 这段代码展示了如何设置主题(`subject`)以及自定义声明(`claims`),并通过指定算法(HMAC SHA-256) 密钥对消息进行签名。 ### 使用Hutool库简化操作 除了上述标准做法外,还可以借助第三方库如Hutool来更便捷地完成相同的工作。该库提供了专门用于处理JWT的功能——`JWTUtil`工具类[^2]: ```java import cn.hutool.extra.jwt.JWT; import cn.hutool.extra.jwt.JWTUtil; @Test public void generateTokenUsingHutool(){ Map<String,Object> payload = new HashMap<>(); payload.put("id", 1); payload.put("username","KBLL"); String token = JWTUtil.createToken(payload,"secret".getBytes()); System.out.println(token); } ``` 这里使用了更加简洁的方式来创建包含有效负载信息的JWT字符串,并指定了加密所需的字节数组形式的秘密钥匙。 ### 解析JWT令牌 对于解析已有的JWT令牌而言,在确保拥有正确的验证密钥前提下,可以通过如下方式进行解码与校验: #### Java自带API实现 当尝试读取由其他服务端签发且可能已经失效或被修改过的JWT时,应该将其包裹在一个异常处理器内以应对潜在错误状况: ```java import java.util.Date; import javax.crypto.spec.SecretKeySpec; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.Jwts; import org.junit.Test; @Test public void parseJwt() throws Exception{ try { Claims claims = Jwts.parserBuilder() .setSigningKey("chengxuyuanchengxuyuanchengxuyuanchengxuyuanchengxuyuan".getBytes()) // 指定签名密钥 .build() .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJLQkwiLCJleHAiOjE3Mjc3NzkxNTR9.7Nt1IbfAZ52PKW5cjjbjr3oND9iaJxvGFO5w5g3uNV8").getBody(); Date expirationTime = claims.getExpiration(); boolean isValid = !new Date().after(expirationTime); System.out.println("Is Valid:" + isValid); System.out.println(claims); } catch (ExpiredJwtException e){ System.err.println("The provided JWT has expired."); } } ``` 此部分代码不仅实现了基本的身份验证逻辑,还加入了针对过期事件的具体捕捉机制。 #### Hutool库实现 同样地,如果选择了Hutool作为辅助开发工具,则可参照下面的例子来进行相应的解析工作: ```java import cn.hutool.extra.jwt.JWTValidator; import cn.hutool.extra.jwt.JWT; import cn.hutool.extra.jwt.exceptions.JWTValidationException; @Test public void verifyAndParseByHutool()throws JWTValidationException{ JWT jwt = JWT.of("your_jwt_string_here"); jwt.setKey("secret_key_as_bytes".getBytes()); if(jwt.validate()){ System.out.println(jwt.getPayloads()); }else{ throw new JWTValidationException("Invalid signature or other issues occurred during validation."); } } ``` 这种方法能够有效地减少编码量的同时保持良好的性能表现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值