拦截器以及添加拦截器以及拦截安全问题-----ThreadLocal

94 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天

大家好!!!!! 我是小杨,今天再给大家分享个拦截器以及并发时的安全问题.

  1. 首先大家都知道在写一个项目登录拦截时,肯定首先想到的就是写个拦截器,再将拦截器添加到WebMvcHandler中去,好,废话不多说,上代码.

1.1 首先我们先写一个拦截器用来拦截的我们的请求 实现该接口 HandlerInterceptor

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从 session  中 拿到用户
        HttpSession session = request.getSession ();
        Object user = session.getAttribute ("user");

        if (user == null){
            response.setStatus (401);
            return false;
        }
        // 为了线程安全   将用户保存到threadLocal中  不需要什么key之类的,因为它是保存在当前线程中的
        UserLocalThread.saveUser ((UserDTO)user);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    //  执行完成后 移除用户  避免内存泄漏

        UserLocalThread.removeUser ();
    }

1.2 后面给大家讲解ThreadLocal,然后我们添加拦截器到我们的spring中,该放行的放行,登录肯定是要放行的等等等。。。。。。

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor (new LoginInterceptor ()).excludePathPatterns (
                 "/user/login",
                 "/user/code",
                 "/shop/**",
                 "/shop-type/**",
                 "/voucher/**"

         );
    }
}

1.3 好了,到这里给大家说一下ThreadLocal这个线程安全类的作用,首先写一个工具类.

private static final ThreadLocal<UserDTO> tl = new ThreadLocal<UserDTO>();

public static void saveUser(UserDTO user){
    tl.set (user);
}

public static  void removeUser(){
    tl.remove ();
}

public static UserDTO getUser(){
    return tl.get ();
}

1.4 相信大家都看到拦截器上的这一串代码 UserLocalThread.saveUser ((UserDTO)user); 这串代码是为了将当前用户保存到当前线程中,相信大家都知道线程与线程之间是相互隔离,我们将自己的用户信息保存到自己当前的线程中,为了在并发时保证安全性,当用户需要取我们的信息时,直接在ThreadLocal中拿就好了。

@GetMapping("/me")
public Result me(){
    // 获取当前登录的用户并返回
    UserDTO user = UserLocalThread.getUser ();
    return Result.ok(user);
}

1.5 还有就是ThreadLocal类的泛型结构,我们尽量不要将用户的完整信息以及一些敏感信息保存到session中响应在浏览器上,并且用户信息越多 session内存占用越多,服务器压力越大,我们可以自定义一些DTO类来返回我们想要的信息就行了。

好啦,今天就讲到这里,有什么不懂得欢迎评论区提问,大家一起解答,下一章给大家讲解tomcat集群时,session不共享得问题,我们应该如何解决??????????????????????????,Bye Bye ~ ~ ~ ~