JWT机制(含代码实现)——简单易懂,代码可用

springCloud中由网关对请求统一进行分发和过滤。

什么是JWT

JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案,是一种紧凑且自包含的,用于在多方传递JSON对象的技术。在单点登录和分布式系统和多有使用
JWT包含三个部分,head,payload,签名,用.分隔开来
jwt模型
JWT头部分是一个描述JWT元数据的JSON对象,通常如下所示。

{
"alg": "HS256",
"typ": "JWT"
}

在上面的代码中,
alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);
typ属性表示令牌的类型,JWT令牌统一写为JWT。
有效载荷
jwt中唯一可以不传任何数据的部分,
最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据
Signature
要创建签名部分,必须采用编码的Header+编码的Payload+秘钥,使用Header中指定的算法,并对其进行签名
例如如要使用HMAC SHA256算法,将按以下方式创建签名:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

最后得到的数据和head,payload用.进行组合,即得到jwt串

解决跨域请求问题

@Bean
    public WebFilter corsFilter() {
        return (ServerWebExchange ctx, WebFilterChain chain) -> {
            ServerHttpRequest request = ctx.getRequest();
            if (CorsUtils.isCorsRequest(request)) {
                ServerHttpResponse response = ctx.getResponse();
                HttpHeaders headers = response.getHeaders();
                指定允许其他域名访问
                headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
                //允许的请求类型,GET,POST
                headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
                
                headers.add("Access-Control-Max-Age", MAX_AGE);
                ///允许的请求头字段
                headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
                headers.add("Access-Control-Expose-Headers", ALLOWED_Expose);
                headers.add("Access-Control-Allow-Credentials", "true");
                if (request.getMethod() == HttpMethod.OPTIONS) {
                    response.setStatusCode(HttpStatus.OK);
                    return Mono.empty();
                }
            }
            return chain.filter(ctx);
        };
    }

穿插了一个小知识,接下来介绍JAVA实现JWT加密认证
有效载荷中包含claims
claims是关于实体(常用的是用户信息)和其他数据的声明,
claims有三种类型: registered, public, and private claims

接下来是Jwt机制的代码实现
定义一个字符用于创造秘钥

private static  final String aesKey="xtasz";

根据提供的信息创建jwt加密串

 public static String BuidJwtString(String userId,String userName){
        //签名算法,选择SHA-256
        SignatureAlgorithm signatureAlgorithm =SignatureAlgorithm.HS256;//这个类在io.jsonwebtoken.*; 别导错了
        //添加构成JWT的参数,入参前面有介绍
        Map<String, Object> headMap = new HashMap<>();
        headMap.put("alg", SignatureAlgorithm.HS256.getValue());//就是HS256
        headMap.put("typ", "JWT");
        //将常量字符串使用base64解码成字节数组
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(aesKey);
        //使用HmacSHA256签名算法生成一个HS256的签名秘钥Key
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
       //创建builder
        JwtBuilder jwtBuilder= Jwts.builder().setHeader(headMap).claim("userId",userId)
                .claim("userName",userName)
                //指定签名的算法和秘钥
                .signWith(signatureAlgorithm,signingKey);
        //如果需要设置过期时间
        long nowTimeMills=System.currentTimeMillis();//获取当前时间
        long expiretime=nowTimeMills+10000;//10000毫秒后过期
        Date date = new Date(expiretime);
        jwtBuilder.setExpiration(date);
        //返回创建好的jwt字符串
        return jwtBuilder.compact();
    }

解密jwt字符串(jwt过期时会抛出异常)

  //解析jwt,返回Claims,可根据key获取载荷信息
    public static Claims parseJwt(String jwtString){
        Claims claims = null;//获取有效载荷中数据
        if(StringUtils.isNotEmpty(jwtString)){
            claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(aesKey))
                    .parseClaimsJws(jwtString).getBody();
        }
        return claims;
    }

我们可以写个测试方法

public static void main(String[] args) {
        String userName ="lee";
        String userId ="009";
     String jwdToken=JwtUtil.BuidJwtString(userName,userId);
        System.out.println(jwdToken);
        Claims claims=JwtUtil.parseJwt(jwdToken);
        System.out.println(claims.get("userName"));

    }

亲测可用
pom jar包地址

<!-- JWT相关 -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

猜你喜欢

转载自blog.csdn.net/qq_41700030/article/details/102729054