<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); } } }
前端存到localStorage,只支持寫入字符串 if(!window.localStorage){ alert("瀏覽器支持localstorage"); return false; }else{ var storage=window.localStorage; //寫入a字段 storage["a"]=1; //寫入b字段 storage.a=1; //寫入c字段 storage.setItem("c",3); console.log(typeof storage["a"]); console.log(typeof storage["b"]); console.log(typeof storage["c"]); }
使用sessionStorage也可以
並發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()即可;