Trial

Phoenix nirvana, bathed in fire.

在SpringBoot中使用JWT

JWT概述

JWT简介

JSON Web Token(JWT)是一种开放的标准(RFC 7519),它定义了一种紧凑的和自包含的方式,用于在JSON对象之间安全传输信息。该信息可以被验证和信任,因为它是数字签名的。JWT可以使用密钥HMAC算法或RSA或ECDSA来签名。

JWT应用场景

授权:这是使用JWT最常见的方案。当用户登录后,每个后续请求将会在header带上JWT,允许用户访问允许使用该令牌的路由、服务和资源。单点登录是当今广泛使用JWT的一个特性,因为它具有较小的开销和易于跨不同域使用的能力。

信息交换:JWT是保证各方之间安全地传输信息的一种好方法。因为JWT可以被签名,例如使用公钥/私钥对,可以确保发件人是他们所说的人。另外,由于使用header和playload计算签名,还可以验证内容是否被篡改。

文本主要介绍如何在SpringBoot中使用,更多的JWT信息可参考RFC文档或者查看《JSON Web Token 入门教程

在SpringBoot使用JWT

在Java语言中,比较流向的JWT库有Nimbus JOSE+JWTJava JWTSpring Security JWT Library等。本文将基于Java JWT来讲解。

本文的开发环境信息为:Spring Boot 2.x、Java JWT3.3.0

首先在项目工程中引用Java JWT

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.3.0</version>
</dependency>

这里将使用HMAC算法来实战。创建JWT的关键代码如下:

public String createJWT(Map<String, String> data) {
        //Header信息
        Map<String, Object> headerClaims = new HashMap<>();
        //类型
        headerClaims.put("typ", "JWT");
        //算法名称
        headerClaims.put("alg", "HS256");
        //密钥
        JWTCreator.Builder builder = JWT.create().withHeader(headerClaims);
        Set<Map.Entry<String, String>> entrySet = data.entrySet();
        //自定义Payload字段
        for (Map.Entry<String, String> entry : entrySet) {
            builder.withClaim(entry.getKey(), entry.getValue());
        }
        Calendar expiredTime = Calendar.getInstance();
        expiredTime.add(Calendar.SECOND, jwtConfig.getExpiredTime());
        try {
            String token = builder
                    //签发人
                    .withIssuer("Trial")
                    //签发时间
                    .withIssuedAt(new Date())
                    // 过期时间
                    .withExpiresAt(expiredTime.getTime())
                    // 创建时间
                    .withIssuedAt(new Date())
                    // 签名
                    .sign(Algorithm.HMAC256(jwtConfig.getJwtSecret()));
            logger.debug("create token:{}", token);
            return token;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException("JWT签名错误!" + e.getMessage(), e);
        }
    }

 

验证JWT的代码如下:

@Override
public Map<String, Claim> verfiyJWT(String token) {
    JWTVerifier verifier = null;
    try {
        verifier = JWT.require(Algorithm.HMAC256(jwtConfig.getJwtSecret())).build();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        throw new RuntimeException("jwt操作失败", e);
    }

    DecodedJWT jwt = null;
    try {
        jwt = verifier.verify(token);
    } catch (TokenExpiredException e) {
        throw new RuntimeException("jwt已过期", e);
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        throw new RuntimeException("jwt验证错误", e);
    }
    Map<String, Claim> claimMap = jwt.getClaims();
    return claimMap;
}

以上只是把核心的代码介绍了一下,有了这个,就很容易个shiro整合了。

相关代码已同步提交到https://gitee.com/tansice/jwt_demo.git