JavaWeb合集16-JWT令牌验证

十六、JWT令牌验证

JWT(JSON Web Token)是一种用于在网络上安全传输信息的紧凑、URL 安全的表示形式。它是一种无状态的身份验证机制,常用于现代Web应用和服务之间传递用户身份信息或授权数据。JWT 设计用于在各方之间安全地传输信息,并且信息是可以被验证和信任的。

JWT 由三个部分组成,它们通过点(.)分隔,头部(Header)、负载(Payload)、签名(Signature)。

使用场景:用户身份验证、单点登录、微服务间的通信、移动应用认证等

用户身份验证流程:用户登录、服务器验证、客户端存储JWT、请求附带JWT、服务器验证JWT。

1、具体实现

1、导入对应的jar包

        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.12.5</version>
        </dependency>

2、创建Jwt工具类

/**
 * jwt工具类
 */
@Slf4j
public class JwtUtil {

    private static final String SECRET = "yhzy"; // 密钥:可任意字符串
    private static final long defaultExpire = 1000 * 60 * 60 * 24 * 7L;//过期时间:7天
    //创建一个jwt密钥 加密和解密都需要用这个玩意
    private static final SecretKey key = Jwts.SIG.HS256.key()
            .random(new SecureRandom(SECRET.getBytes(StandardCharsets.UTF_8)))
            .build();

    private JwtUtil() {
    }

    /**
     * 使用默认过期时间(7天),生成一个JWT
     *
     * @param claims   JWT中的数据
     * @return
     */
    public static String createToken( Map<String, Object> claims) {
        return createToken(claims, defaultExpire);
    }

    /**
     * 生成token
     *
     * @param claims   请求体数据
     * @param expire   过期时间 单位:毫秒
     * @return token
     */
    public static String createToken(Map<String, Object> claims, Long expire) {
        JwtBuilder builder = Jwts.builder();
        Date now = new Date();
        // 生成token
        builder.issuer("yhzy.fun") //签发者
                .claims(claims) //数据
                .issuedAt(now) //签发时间
                .expiration(new Date(now.getTime() + expire)) //过期时间
                .signWith(key); //签名方式
        builder.header().add("JWT", "JSpWdhuPGblNZApVclmX");
        return builder.compact();
    }

    /**
     * 解析token
     *
     * @param token jwt token
     * @return Claims
     */
    public static Claims parseToken(String token) {
        try {
            return Jwts.parser()
                    .verifyWith(key)  //密钥
                    .build() 
                    .parseSignedClaims(token) 
                    .getPayload();
        } catch (Exception e) {
            if (e instanceof ExpiredJwtException) {
                // 判断JWT是否过期了 如果过期会抛出ExpiredJwtException异常
                throw new JwtVerificationException("token已过期");
            }
            if (e instanceof JwtException) {
                throw new JwtVerificationException("token已失效");
            }
            log.info("jwt解析失败" + e);
            throw new JwtVerificationException("token解析失败");
        }
    }
}

3、测试:生成token 和解析 token ,也可以通过在线工具解析测试:https://tooltt.com/jwt-decode

@SpringBootTest
class ApplicationTests {
    //生成token
    @Test
     void  createJwtTest(){
        //创建一个Map对象,将数据封装到Map中,并生成token
        Map<String, Object> claims = Map.of("id", 1, "username", "yhzy");
       //调用工具类生成token
       String token=JwtUtil.createToken(claims);
       System.out.println(token);
    }

    //解析token
    @Test
    void  parseJwtTest(){
      //解析token:将生成的Token进行解析
      String token="eyJKV1QiOiJKU3BXZGh1UEdibE5aQXBWY2xtWCIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJ5aHp5LmZ1biIsImlkIjoxLCJ1c2VybmFtZSI6InloenkiLCJpYXQiOjE3Mjk2NzUxODIsImV4cCI6MTczMDI3OTk4Mn0.R828xZjAAof-KOMxppTtZkqL58TbDwgXUeG9fCTM-RA";
      Claims claims = JwtUtil.parseToken(token); //解析token
      System.out.println(claims);
    }
}
上一篇:ROSTCM6+Gephi的网络语义分析详细教程(附案例实战)


下一篇:【Triton 教程】融合 Softmax (Fused Softmax)-单元测试