package com.om.interceptor; import com.alibaba.fastjson.JSON; import com.om.constant.RedisConstant; import com.om.exception.CustomerAuthenticationException; import com.om.utils.*; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * jwt令牌校验的拦截器 */ @Component @Slf4j public class JwtTokenUserInterceptor implements HandlerInterceptor { @Resource private JwtUtils jwtUtils; @Resource private RedisTemplate redisTemplate; /** * 校验jwt * * @param request * @param response * @param handler * @return * @throws Exception */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //判断当前拦截到的是Controller的方法还是其他资源 if (!(handler instanceof HandlerMethod)) { //当前拦截到的不是动态方法,直接放行 return true; } //2、校验令牌 try { this.validateToken(request); } catch (CustomerAuthenticationException ex) { response.setContentType("application/json;charset=UTF-8"); // 设置字符集为 UTF-8 String message = ex.getMessage(); response.setStatus(ResultCode.NO_AUTH); response.getWriter().write(JSON.toJSONString(Result.error().message(message).result(ResultCode.NO_AUTH))); return false; } return true; } /** * 验证token信息 */ private void validateToken(HttpServletRequest request) { //从headers头部获取token信息 String token = request.getHeader("token"); //如果请求头部中没有携带token 则从请求的参数中中获取token if (StringUtils.isEmpty(token)) { token = request.getParameter("token"); //从参数中获取 } //如果请求参数中也没有携带token信息 则抛出异常 if (StringUtils.isEmpty(token)) { throw new CustomerAuthenticationException("token不存在"); } //从token中获取用户id Integer uId = jwtUtils.getUserIdFromToken(token); //判断 用户id 是否为空 if (StringUtils.isEmpty(uId)) { throw new CustomerAuthenticationException("token解析失败"); } //判断redis中是否存在token信息 String tokenKey = RedisConstant.USER_TOKEN_PREFIX + uId; String redisToken = (String) redisTemplate.opsForValue().get(tokenKey); //判断redis中是否存在token信息 如果为空 则表示token已经失效、 if (StringUtils.isEmpty(redisToken)) { throw new CustomerAuthenticationException("token已过期"); } //如果token和redis中的token不一致 则验证失败 if (!token.equals(redisToken)) { throw new CustomerAuthenticationException("token验证失败"); } //设置 用户id UserContext.setUserId(uId); } }