JWTToken 工具类和并发ThreadLocal的使用
Posted gaomanito
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JWTToken 工具类和并发ThreadLocal的使用相关的知识,希望对你有一定的参考价值。
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>3.2.0</version>
</dependency>
package com.chitic.common.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; import com.chitic.bank.model.Userinfo; import com.chitic.bank.web.exception.UnauthorizeException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @author GX * @version 1.0*/ public class JWTToken { /** * 生成token * @return * @throws Exception */ public static String createToken(Userinfo user) throws Exception{ // 签发时间 Date iatDate=new Date(); // 过期时间-outTime分钟过期 Calendar nowTime=Calendar.getInstance(); nowTime.add(Calendar.MINUTE, ValuesUtil.OutTime); Date expiresDate=nowTime.getTime(); Map<String,Object> map=new HashMap<String,Object>(); map.put(ParamsUtil.Alg_Key, ValuesUtil.Alg_RS256); map.put(ParamsUtil.Typ_Key, ValuesUtil.Typ_JWT); String token=""; token=JWT.create() .withHeader(map) .withClaim(ParamsUtil.User_Key, user.getUsername()) .withClaim(ParamsUtil.Id_Key, user.getId()) .withClaim(ParamsUtil.Role_Key, user.getRole()) .withClaim(ParamsUtil.Rights_Key,user.getRights()) .withExpiresAt(expiresDate)//设置过期时间-过期时间要大于签发时间 .withIssuedAt(iatDate)//设置签发时间 .sign(Algorithm.HMAC256(ValuesUtil.SECRET));//加密 return token; } /** * 解密token * @param token * @return * @throws Exception */ public static Map<String,Claim> verifyToken(String token) throws Exception { JWTVerifier verifier=JWT.require(Algorithm.HMAC256(ValuesUtil.SECRET)).build(); DecodedJWT jwt=null; try { jwt=verifier.verify(token); } catch (Exception e) { // throw new RuntimeException("登录已失效,请重新登录"); throw new UnauthorizeException(1006, "登录已失效,请重新登录"); } return jwt.getClaims(); } }
private void doUser(ProceedingJoinPoint pjd) throws Exception { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //使用MDC,需要引入log4j
MDC.clear(); String token=request.getHeader(ParamsUtil.Token_Key); MethodSignature methodSignature = (MethodSignature) pjd.getSignature(); Method method = methodSignature.getMethod(); boolean noAuthorize = method.isAnnotationPresent(NoAuth.class); if (!noAuthorize) { Map<String, Claim> claim=JWTToken.verifyToken(token); String username=claim.get(ParamsUtil.User_Key).asString(); int user_id=claim.get(ParamsUtil.Id_Key).asInt(); int role=claim.get(ParamsUtil.Role_Key).asInt(); Integer rights=null; if(!StringUtil.checkObj(claim.get(ParamsUtil.Rights_Key))){ rights=claim.get(ParamsUtil.Rights_Key).asInt(); } if (StringUtil.isBlank(username) || StringUtil.checkObj(user_id) || StringUtil.checkObj(role)) { throw ChiticException.of(ChiticResponseCode.ACCESS_DENY); } HashMap<String,Object> params=new HashMap<String,Object>(); params.put(ParamsUtil.User_Sn_Key, username); params.put(ParamsUtil.User_Id_Key, user_id); Userinfo user=userService.findUserBySNId(params); if (null == user) { throw ChiticException.of(ChiticResponseCode.userLoginNotFound); }else{ if(StringUtil.checkObj(user.getRole())||user.getRole()!=role){ throw ChiticException.of(ChiticResponseCode.Rights_Change); } int user_rights=user.getRights()==null||user.getRights().toString().equals("")?null:user.getRights(); if(user_rights!=rights){ throw ChiticException.of(ChiticResponseCode.Rights_Change); } } UserThreadLocal.set(UserCacheInfo.builder() .userId(user.getId()) .username(user.getUsername()) .role(user.getRole()) .ismanage(user.getRights()) .build()); MDC.put(ParamsUtil.User_Sn_Key, username); MDC.put(ParamsUtil.User_Id_Key, String.valueOf(user_id)); MDC.put(ParamsUtil.Role_Key, String.valueOf(user.getRole())); if (method.isAnnotationPresent(RoleAdmin.class) && !ValuesUtil.isAdminRole()) { throw ChiticException.of(ChiticResponseCode.ACCESS_DENY); } } }
并发ThreadLocal的使用
ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
使用
//创建ThreadLocal,里面存登录的用户信息 private static final ThreadLocal<UserCacheInfo> local = new ThreadLocal<>(); //最常用的三个方法 //local.set(); //local.get(); //local.remove(); try { //用户登录成功之后,将其用户信息放到local中 local.set(user); doUser(pjp);//用户信息校验 } catch (Exception e) { log.error("请求出错,错误信息: {}",e); } catch (Throwable e) { log.error("请求出错,错误信息: {}",e); } finally { //注意要关闭 if (null != UserThreadLocal.get()) { UserThreadLocal.remove(); } } //使用的话调用local.get()即可;
以上是关于JWTToken 工具类和并发ThreadLocal的使用的主要内容,如果未能解决你的问题,请参考以下文章
Java并发编程的艺术 -- 原子操作类和并发工具类(第七八章)