统一处理token的思路

统一处理token

拦截器

拦截器( Interceptor)是一种动态拦截方法调用的机制

在这里插入图片描述
拦截器和过滤器的区别

在这里插入图片描述

1、处理token的逻辑代码

@Service
public class UserService {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public User getUserByToken(String token) {
        String redisUserValue = redisTemplate.opsForValue().get(token);
        if (StringUtils.isNotEmpty(redisUserValue)) {
            // 说明用户是登录状态
            try {
                // 刷新 token的存储时间
                redisTemplate.expire(token, 1, TimeUnit.HOURS);
                return OBJECT_MAPPER.readValue(redisUserValue, User.class);
            } catch (IOException e) {
                LOGGER.error("解析token发生异常", e);
            }
        }
        // 用户未登录
        return null;
    }
}

2、自定义一个方法注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Authorization {
}
// 用来标记需要Authorization(授权) 的方法

3、编写TokenInterceptor 拦截器

@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 只需要拦截带有token的请求
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Authorization annotation = handlerMethod.getMethod().getAnnotation(Authorization.class);
            if (annotation == null) {
                // 请求方法上没有该注解的话,说明该方法没有携带token值,直接放行即可
                return true;
            }
        }
        // 有注解的情况 token 能解析出来的情况
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotEmpty(token)) {
            User user = userService.getUserByToken(token);
            if (null != user) {
                UserThreadLocal.set(user);
                // 放行即可
                return true;
            }
        }
        // token解析异常的情况
        response.setStatus(444);
        return false;
    }
}

4、UserThreadLocal

public class UserThreadLocal {
    private static final ThreadLocal<User> LOCAL = new ThreadLocal<User>();

    private UserThreadLocal() {

    }

    public static void set(User user) {
        LOCAL.set(user);
    }

    public static User get() {
        return LOCAL.get();
    }

	 /**
     * 防止内存泄漏
     */
    public static void remove(){
        LOCAL.remove();
    }
}

5、注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private TokenInterceptor tokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
    }
}

使用的时候,请求方法上面本来携带token的参数,就可以用注解@Authorization 代替,入参就可以不用编写了

ThreadLocal ???

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值