统一token处理

本文介绍了如何通过在SpringMVC中使用ThreadLocal和拦截器,减少代码重复,实现对每个请求的token解析和用户身份验证,仅在有效token下存储User对象,提高效率并简化代码。
摘要由CSDN通过智能技术生成

我们发现 每一个控制方法中都需要解析token , 获取当前用户id , 代码重复度比较高

也就是每次请求都会获取解析token 很麻烦

基于ThreadLocal + 拦截器的形式统一处理

 

拦截器

是一种动态拦截方法调用的机制;

类似于Servlet 开发中的过滤器Filter,用于对处理器进行前置处理和后置处理。

threadlocal

线程内部的存储类,赋予了线程存储数据的能力。

线程内调用的方法都可以从ThreadLocal中获取同一个对象。

多个线程中ThreadLocal数据相互隔离

Threadlocal使用方法很简单

ThreadLocal<T> threadLocal = new ThreadLocal<T>();
threadLocal.set() //将数据绑定到当前线程
threadLocal.get() //从当前线程中获取数据

Thread工具类



import com.tanhua.domain.User;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 
 * @Date: 
 * @Message: Talk is cheap. Show me the code.
 * @Description:
 */
public class UserHolder {
    private static ThreadLocal<User> t1 = new ThreadLocal<>();

    // 设置
    public static void set(User user) {
        t1.set(user);
    }

    // 获取
    public static User get() {
        return t1.get();
    }

    // 删除
    public static void remove() {
        t1.remove();
    }

    // 获取用户id
    public static Long getUserId() {
        if (t1.get() != null) {
            return t1.get().getId();
        }
        return null;
    }

    // 获取用户手机号
    public static String getUserMobile() {
        if (t1.get() != null) {
            return t1.get().getMobile();
        }
        return null;
    }

}

定义拦截器,在前置拦截方法preHandle中解析token并验证有效性,如果失效返回状态码401。如果有效,解析User对象,存入ThreadLocal中

import cn.hutool.core.util.StrUtil;
import com.tanhua.JWTUtil;
import com.tanhua.domain.User;
import io.jsonwebtoken.Claims;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 
 * @Date: 
 * @Message: Talk is cheap. Show me the code.
 * @Description:
 */
public class TokenIterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 获取token
        String token = request.getHeader("Authorization");
        // 验证token
        if (StrUtil.isBlank(token)) {
            return false;
        }
        // 解析token
        Claims claims = JWTUtil.parseToken(token, "tanhua");
        // 验证token里面的键值
        if (claims == null) {
            return false;
        }
        // 构造user 对象 存入UserHolder
        User user = new User();
        user.setId(Long.valueOf(claims.get("userId").toString()));
        user.setMobile(claims.get("mobile").toString());
        UserHolder.set(user);

        return true;
    }
}

 拦截器需要注册到MVC容器中 使用 @Configuration 注解实现

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 
 * @Date: 
 * @Message: Talk is cheap. Show me the code.
 * @Description:
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * @Description: 添加拦截器
     * @Param: [registry]
     * @return: void
     * @Author: 
     * @Date: 
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器 TokenIterceptor
        registry.addInterceptor(new TokenIterceptor())
                .addPathPatterns(("/**"))
                .excludePathPatterns("/user/login","/user/loginVerification");
    }
}

然后 使用的时候也很简单 只需要 

        Long userId = UserHolder.getUserId();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值