1.新增登录用户对象 UserInfo
@Data public class UserInfo implements Serializable { private Long id; private Long userId; private String nickname; private String mobile; }
2.新增当前线程对象 UserContext
public class UserContext { private static ThreadLocal<UserInfo> userThread = new ThreadLocal<>(); public static void set(UserInfo userInfo) { userThread.set(userInfo); } public static UserInfo get() { return userThread.get(); } /** * 获取当前登录用户的ID * 未登录返回null * * @return */ public static Long getUserId() { UserInfo user = get(); if (user != null && user.getUserId() != null) { return user.getUserId(); } return null; } //防止内存泄漏 public static void remove() { userThread.remove(); } }
3.拦截器保存 用户信息,登录校验成功后 保存用户登录信息。
UserInfo userInfo = new UserInfo();
userInfo.setId(user.getId());
userInfo.setUserId(user.getUserId());
userInfo.setMobile(user.getMobile());
userInfo.setNickname(user.getNickname());
UserContext.set(userInfo);
@Slf4j
public class AuthorizationInterceptor implements HandlerInterceptor {@Value("${refreshTokenExpireTime}")
private String refreshTokenExpireTime;
@Autowired
private IUserService userService;@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
String requestURI = request.getRequestURI();
//对于不用进行验证的接口直接放行
if (ReleaseAddressUtil.confirm(requestURI)) {
return true;
}
String token = request.getHeader(CommonConstant.AUTHORIZATION);
if (token == null) {
// 获取当前请求类型
String httpMethod = request.getMethod();
// 获取当前请求URI
log.info("当前请求 {} Authorization属性(Token)为空 请求类型 {}", requestURI, httpMethod);
// mustLoginFlag = true 开启任何请求必须登录才可访问
this.response401(request, response, "请先登录");
return false;
}
String mobile = null;
String userId = null;
try {
mobile = JwtUtil.getMobile(token);
userId = JwtUtil.getUserId(token);
} catch (Exception e) {
e.printStackTrace();
log.info(e.getMessage());
this.response401(request,response,"token错误!");
return false;
}
if (StringUtils.isEmpty(mobile)) {
this.response401(request, response, "token错误!");
return false;
}
if (StringUtils.isEmpty(userId)) {
this.response401(request, response, "token错误!");
return false;
}
User user = userService.getByUserId(Long.valueOf(userId));
if (user == null) {
this.response401(request, response, "账号不存在!");
return false;
}
if (user.getStatus() != null && CommonConstant.DISABLE.equals(user.getStatus())) {
this.response401(request, response, "帐号已被锁定,禁止登录!");
return false;
}
try {
if (JwtUtil.verify(token) && RedisUtil.hasKey(RedisKeyPrefix.SFC_REFRESH_TOKEN + mobile)) {
Object currentTimeMillisRedis = RedisUtil.get(RedisKeyPrefix.SFC_REFRESH_TOKEN + mobile);
// 获取AccessToken时间戳,与RefreshToken的时间戳对比
if (JwtUtil.getCurrentTimeMillis(token).equals(currentTimeMillisRedis.toString())) {
UserInfo userInfo = new UserInfo();
userInfo.setId(user.getId());
userInfo.setUserId(user.getUserId());
userInfo.setMobile(user.getMobile());
userInfo.setNickname(user.getNickname());
UserContext.set(userInfo);
return true;
}
}
} catch (Exception e) {
// 认证出现异常,传递错误信息msg
String msg = e.getMessage();
this.response401(request, response, msg);
return false;
}
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, ModelAndView modelAndView) {}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, Exception e) {//关闭threadLocal
UserContext.remove();
}/**
* 缺少权限内部转发至401处理
*
* @param request
* @param response
* @param msg
*/
private void response401(ServletRequest request, ServletResponse response, String msg) {
HttpServletRequest req = (HttpServletRequest) request;
try {
req.getRequestDispatcher("/app/user/login/unauthorized?message=" + msg).forward(request, response);
} catch (Exception e) {
log.error("未授权登录{}", e);
}
}
}