- <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() 即可;
来源: http://www.bubuko.com/infodetail-3059133.html