springboot-gradle-token

本文深入解析JWT(JSON Web Token)的概念及其在Java中的应用。详细介绍了token的结构、使用场景及如何通过Java-jwt框架生成与验证token。此外,还提供了自定义密钥、设置过期时间等高级操作的代码示例。
摘要由CSDN通过智能技术生成

token的使用

token官网: https://jwt.io/

token概念
	 token 令牌:
    JWT: JSON Web Token 是一种标准
    java-jwt 框架 是java实现的JWT标准的一个框架

    JWT标准: token由三部分组成,每部分之间使用'.'分开
    第一部分: 头(header)
        里面保存了该token的加密方式
    第二部分: 负载(payload)
        里面保存了用户信息/token的信息(id/过期时间等等)
    第三部分: 校验信息

    第一部分和第二部分是JSON格式的数据使用Base64编码后的信息
    注意: 该部分的信息是明文,不能存储敏感数据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

具体代码如下:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.lanou3g.tokendemo111.utils.JwtUtils;
import org.junit.Test;

import java.util.Date;

public class TokenTest {

    // 自定义密钥,可以自己随便写,越复杂越好
    public static final String SECRET_KEY = "53g2jkj2be215k1b1";

    @Test
    public void createToken() {
        // 创建token
        String token = JWT.create()
                // 在负载中添加自定义的数据
                .withClaim("userId", 1001)
                .withClaim("username", "admin")
                // 发布时间,也就是生成时间,可以稍微记录一下上次的登录时间
                .withIssuedAt(new Date())
                // 设置该token的过期时间
                // 10秒钟后该token过期
                .withExpiresAt(new Date(System.currentTimeMillis() + 100000))
                // sign要在最后调用,使用Algorithm选择加密方式,常用HMAC256
                .sign(Algorithm.HMAC256(SECRET_KEY));
        System.out.println(token);
        // 生成后的token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NDEwNDEzNDksInVzZXJJZCI6MTAwMSwiaWF0IjoxNTQxMDQxMzM5LCJ1c2VybmFtZSI6Imt0bG42NjYifQ.tU_kElllOPZq4A67VEJCODlwD3OFi6ntC4V8ARO60Q0
    }

    @Test
    public void require() {
        // 根据校验规则HMAC256生成校验对象
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET_KEY)).build();
        try {
            // 校验前端发送过来的token是否合法
            // 如果合法会返回一个解码后的jwt对象
            // 如果不合法,会抛出xxx异常
            // verify参数填写上面方法生成的token
            DecodedJWT jwt = verifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NDEwNDMzNzcsInVzZXJJZCI6MTAwMSwiaWF0IjoxNTQxMDQzMjc3LCJ1c2VybmFtZSI6Imt0bG42NjYifQ.fCFxLol9V_a0DBdxi63jgtC2_6s2C81l9CpXd0oN85s");
            System.out.println(jwt.getHeader());
            System.out.println(jwt.getPayload());
        } catch (TokenExpiredException e) {
            System.out.println("Token已经过期");
        } catch (SignatureVerificationException e) {
            System.out.println("Token不合法");
        } catch (Exception e) {
            System.out.println("认证失败");
        }
    }

}


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

下面我们来模拟一下如果token到期时间高于80%,就返回给他一个新的token,代码如下:

新建一个工具类:

在这里插入图片描述


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;

public class JwtUtils {

    /**
     * 默认过期时间30分钟
     *
     * @param userId 用户ID
     * @return token
     */
    public static String newToken(Long userId) {
        // 为一个用户设置token并设置默认到期时间
        return newToken(userId, Constants.DEFAULT_EXPIRED_SECONDS);
    }

    /**
     * @param userId         用户ID
     * @param expiredSeconds 过期时长
     * @return token
     */
    public static String newToken(Long userId, long expiredSeconds) {
        return JWT.create()
                .withClaim("userId", userId)
                // 发布时间
                .withIssuedAt(new Date())
                // 到期时间
                .withExpiresAt(new Date(System.currentTimeMillis() + expiredSeconds * 1000))
                // 选择加密方式
                .sign(Algorithm.HMAC256(Constants.SECRET_KEY));
    }

    /**
     * 校验token是否合法
     *
     * @param token 需要校验的token
     * @return 是否合法
     */
    public static boolean checkToken(String token) {
        // 根据校验规则HMAC256生成校验对象
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(Constants.SECRET_KEY)).build();
        try {
            // 校验token是否合法
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 刷新token
     *
     * @param token 原token
     * @return 新token
     */
    public static String refreshToken(String token) {
        // 进行Base64解码
        DecodedJWT jwt = JWT.decode(token);
        // 获得解码后token里的负载中的用户ID
        Long userId = jwt.getClaim("userId").asLong();
        // 调用上面的创建token的方法创建新的token
        return newToken(userId);
    }

    /**
     * token到期时间高于80%,就返回给他一个新的token,并做校验
     * @param token
     * @return
     */
    public static String autoRequire(String token) {
        // 校验token
        boolean check = checkToken(token);
        if (check) {
            // 解码
            DecodedJWT jwt = JWT.decode(token);
            // 计算时间是否超过80%
            long current = System.currentTimeMillis() / 1000;
            // 获取开始时间
            Long start = jwt.getClaim("iat").asLong();
            // 获取结束时间
            Long end = jwt.getClaim("exp").asLong();
            if ((current - start) * 1.0 / (end - start) > 0.8) {
                // 时间超过80%返回新的token
                return refreshToken(token);
            } else {
                // 返回原来的token
                return token;
            }
        } else {
            throw new JWTVerificationException("token不合法");
        }
    }

}


回到之前的测试类:

在这里插入图片描述

在这里插入图片描述

附加: gethub 源码地址: https://github.com/JianJieMing/JianJieMing_JAVA/tree/master/token-demo-11-1

源码上有个基于token模拟用户登录的demo,token到期无法访问指定页面(附加拦截器,异常处理)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值