springboot 整合jwt

关于jwt的实现原理,可以自行查找资料。我们只关注如何实现。

一:首先引入依赖。目前有两个库实现了jwt的功能。

 

两个库都实现了jwt功能,只不过使用的api不太相同。使用其中任何一个都可以。通过查看maven官网,jjwt好久没有更新了。而java-jwt一直有更新。为了以后少点麻烦还是使用java-jwt.

二:创建jwt帮助类,实现三个功能,

1.创建token

最关键需要两个变量,一个是到期时间,一个是秘钥

private static final long EXPIRE_TIME = 5 * 60 * 1000;
private static final String TOKEN_SECRET = "ds_xjc_jwt_secret";

public static String getToken(User user) {
//        Calendar instance = Calendar.getInstance();
//        instance.add(Calendar.DATE, 7);/*默认令牌过期时间7天 财哥 2022/4/8 15:33*/
//        instance.getTime();
        Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        JWTCreator.Builder builder = JWT.create();
        builder.withClaim("xmId", user.getXmId()).withClaim("qsId",user.getQsId()).withClaim("userName", user.getUserName());
        //builder.withAudience(user.getXmId()).withAudience(user.getQsId()).withAudience(user.getUserName());
        return builder.withExpiresAt(expiresAt).sign(Algorithm.HMAC256(TOKEN_SECRET));/* 完成过期时间配置及加密 2022/4/8 15:34*/
    }

2.验证token 如果不报异常就验证正确

public static boolean checkTokenVerify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (SignatureVerificationException e) {
            log.error("无效签名! 错误 ->", e);
            return false;
        } catch (TokenExpiredException e) {
            log.error("token过期! 错误 ->", e);
            return false;
        } catch (AlgorithmMismatchException e) {
            log.error("token算法不一致! 错误 ->", e);
            return false;
        } catch (Exception e) {
            log.error("token无效! 错误 ->", e);
            return false;
        }
    }

3.获取token中数据,因为和验证调的是一样的api,只有先验证成功才能取数据,否则会出错

public static Map<String, String> parseToken(String token) {
        HashMap<String, String> map = new HashMap<String, String>();
        DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).build().verify(token);
//        Claim xmId = decodedjwt.getClaim("xmId");
//        Claim qsId = decodedjwt.getClaim("qsId");
//        Claim userName = decodedjwt.getClaim("userName");
        map.put("xmId", decodedjwt.getClaim("xmId").asString());
        map.put("qsId", decodedjwt.getClaim("qsId").asString());
        map.put("userName", decodedjwt.getClaim("userName").asString());
        map.put("timeStamp",decodedjwt.getExpiresAt().toString());/* 过期时间  2022/4/8 21:49*/
        return map;
    }

三 集成进springboot,拦截请求

这里也有两种方式,一种是通过注解的方式加在指定的控制器上,另外一种是对特定的url进行拦截。

1. 注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface JwtToken {
    boolean required() default true;
}

2.写拦截器

    @Autowired
    JwtUtils jwtUtil;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        String token = request.getHeader("token"); // 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过 通过注解方式才需要以下代码
        /*if (!(object instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        //检查是否有JwtToken注释,有则跳过认证
        if (method.isAnnotationPresent(JwtToken.class)) {
            JwtToken  passToken = method.getAnnotation(JwtToken.class);
            if (passToken.required()) {
                return true;
            }
        }*/
        //为空就返回错误
        if (null == token || "".equals(token.trim())) {
            return false;
        }
        if(jwtUtil.checkTokenVerify(token)){
//            Map<String, String> map = jwtUtil.parseToken(token);
//            String userId = map.get("userId");
//            String userRole = map.get("userRole");
//            long timeOfUse = System.currentTimeMillis() - Long.parseLong(map.get("timeStamp"));
//        //1.判断 token 是否过期
//        if (timeOfUse < refreshTime) {
//            log.info("token验证成功");
//            return true;
//        }
//        //超过token刷新时间,刷新 token
//        else if (timeOfUse >= refreshTime && timeOfUse < expiresTime) {
//            httpServletResponse.setHeader("token",tokenUtil.getToken(userId,userRole));
//            log.info("token刷新成功");
//            return true;
//        }
//        //token过期就返回 token 无效.
//        else {
//            throw new TokenAuthExpiredException();
//        }
            return true;
        }else{
            return false;
        }
    }

3.集成

@Configuration
public class JwtWebMvcConfigurer implements WebMvcConfigurer {
    @Autowired
    JwtHandlerInterceptor jwtHandlerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtHandlerInterceptor).addPathPatterns("/mobile/**").excludePathPatterns("/mobile/login");//针对指定路径进行拦截,排除登录页面
    }
}

四 使用

1. 如果通过注解方式的,就在方法上加注解

2.如果是通过url的就不用加注解

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值