实现登录拦截功能

1.4、实现登录拦截功能

温馨小贴士:tomcat的运行原理

当用户发起请求时,会访问我们像tomcat注册的端口,任何程序想要运行,都需要有一个线程对当前端口号进行监听,tomcat也不例外,当监听线程知道用户想要和tomcat连接连接时,那会由监听线程创建socket连接,socket都是成对出现的,用户通过socket像互相传递数据,当tomcat端的socket接受到数据后,此时监听线程会从tomcat的线程池中取出一个线程执行用户请求,在我们的服务部署到tomcat后,线程会找到用户想要访问的工程,然后用这个线程转发到工程中的controller,service,dao中,并且访问对应的DB,在用户执行完请求后,再统一返回,再找到tomcat端的socket,再将数据写回到用户端的socket,完成请求和响应

通过以上讲解,我们可以得知 每个用户其实对应都是去找tomcat线程池中的一个线程来完成工作的, 使用完成后再进行回收,既然每个请求都是独立的,所以在每个用户去访问我们的工程时,我们可以使用threadlocal来做到线程隔离,每个线程操作自己的一份数据

温馨小贴士:关于threadlocal

如果小伙伴们看过threadLocal的源码,你会发现在threadLocal中,无论是他的put方法和他的get方法, 都是先从获得当前用户的线程,然后从线程中取出线程的成员变量map,只要线程不一样,map就不一样,所以可以通过这种方式来做到线程隔离

拦截器代码

Java 复制代码
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       //1.获取session
        HttpSession session = request.getSession();
        //2.获取session中的用户
        Object user = session.getAttribute("user");
        //3.判断用户是否存在
        if(user == null){
              //4.不存在,拦截,返回401状态码
              response.setStatus(401);
              return false;
        }
        //5.存在,保存用户信息到Threadlocal
        UserHolder.saveUser((User)user);
        //6.放行
        return true;
    }
}

让拦截器生效

java 复制代码
@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 登录拦截器
        registry.addInterceptor(new LoginInterceptor())
                .excludePathPatterns(
                        "/shop/**",
                        "/voucher/**",
                        "/shop-type/**",
                        "/upload/**",
                        "/blog/hot",
                        "/user/code",
                        "/user/login"
                ).order(1);
        // token刷新的拦截器
        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);
    }
}

1.5、隐藏用户敏感信息

我们通过浏览器观察到此时用户的全部信息都在,这样极为不靠谱,所以我们应当在返回用户信息之前,将用户的敏感信息进行隐藏,采用的核心思路就是书写一个UserDto对象,这个UserDto对象就没有敏感信息了,我们在返回前,将有用户敏感信息的User对象转化成没有敏感信息的UserDto对象,那么就能够避免这个尴尬的问题了

在登录方法处修改

java 复制代码
//7.保存用户信息到session中
session.setAttribute("user", BeanUtils.copyProperties(user,UserDTO.class));

在拦截器处:

java 复制代码
//5.存在,保存用户信息到Threadlocal
UserHolder.saveUser((UserDTO) user);

在UserHolder处:将user对象换成UserDTO

java 复制代码
public class UserHolder {
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();

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

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

    public static void removeUser(){
        tl.remove();
    }
}
相关推荐
笨笨饿1 分钟前
80_聊聊SPI以及它们的变体
linux·c语言·网络·stm32·单片机·算法·个人开发
神奇椰子7 分钟前
Linux系统更换软件源说明文档
linux·运维·服务器
ITyunwei098710 分钟前
数字化转型与遗留系统:如何为老旧的IT系统“减负“并注入新活力?
运维·网络·数据库
Python私教12 分钟前
跨境电商浏览器自动化:Claude Code 集成 AdsPower MCP 实战
运维·自动化
风曦Kisaki25 分钟前
#Linux Shell 编程入门 Day05 :awk文本数据处理基础
linux·运维
wanhengidc34 分钟前
BGP服务器的功能是什么
运维·服务器·安全·web安全·智能手机
剑神一笑1 小时前
Linux tree 命令深度解析:从目录遍历到树形可视化的完整实现
linux·运维·elasticsearch
xhbh6661 小时前
从零实现Linux软路由:报文转发配置+静态路由+NAT实战
网络·端口转发·流量端口转发·ssh端口转发·端口转发工具
小小的木头人1 小时前
Docker Compose 镜像检测脚本(支持自动扫描 + 手动输入 YAML)
运维·docker·容器
wangl_921 小时前
Modbus RTU 与 Modbus TCP 深入指南-决策树与选型建议
网络·网络协议·tcp/ip·tcp·modbus·rtu