在不使用 Spring Security 的情况下获取用户登录参数

1. 首先我们应该明确用户登录参数应该是在请求头里被携带到后端接口的,那么我们首先应该有一个类用于拦截请求,获取信息,如下:通过实现 Filter 重写 doFilter 方法来获取请求头中信息并放行

java 复制代码
@RequiredArgsConstructor
public class UserTransmitFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String username = httpServletRequest.getHeader("username");
        if(StringUtils.isNotBlank(username)){
            String userId = httpServletRequest.getHeader("id");
            UserInfoDTO userInfoDTO = new UserInfoDTO(username,userId);
            UserContext.setUser(userInfoDTO);
        }

        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            UserContext.removeUser();
        }
    }
}

2.将这个过滤器注册为 Spring 的一个 Bean

java 复制代码
@Configuration
public class UserConfiguration {

    /**
     * 用户信息传递过滤器
     */
    @Bean
    public FilterRegistrationBean<UserTransmitFilter> globalUserTransmitFilter() {
        FilterRegistrationBean<UserTransmitFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new UserTransmitFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(0);
        return registration;
    }

}

3. 通过 ThreadLocal 保存当前线程的用户信息

java 复制代码
public final class UserContext {

    private static final ThreadLocal<UserInfoDTO> USER_THREAD_LOCAL = new TransmittableThreadLocal<>();

    /**
     * 设置用户至上下文
     *
     * @param user 用户详情信息
     */
    public static void setUser(UserInfoDTO user) {
        USER_THREAD_LOCAL.set(user);
    }

    /**
     * 获取上下文中用户 ID
     *
     * @return 用户 ID
     */
    public static String getUserId() {
        UserInfoDTO userInfoDTO = USER_THREAD_LOCAL.get();
        return Optional.ofNullable(userInfoDTO).map(UserInfoDTO::getId).orElse(null);
    }

    /**
     * 获取上下文中用户名称
     *
     * @return 用户名称
     */
    public static String getUsername() {
        UserInfoDTO userInfoDTO = USER_THREAD_LOCAL.get();
        return Optional.ofNullable(userInfoDTO).map(UserInfoDTO::getUsername).orElse(null);
    }

    /**
     * 清理用户上下文
     */
    public static void removeUser() {
        USER_THREAD_LOCAL.remove();
    }
}

主要的逻辑代码如上,大家可以根据自己的项目进行修改

相关推荐
砍材农夫16 小时前
spring-ai 第四多模态API
java·人工智能·spring
她说..19 小时前
Java 对象相关高频面试题
java·开发语言·spring·java-ee
庞轩px19 小时前
深入理解 sleep() 与 wait():从基础到监视器队列
java·开发语言·线程··wait·sleep·监视器
皮皮林55120 小时前
面试官:ZSet 的底层实现是什么?
java
码云数智-大飞21 小时前
C++ RAII机制:资源管理的“自动化”哲学
java·服务器·php
2601_9498165821 小时前
Spring+Quartz实现定时任务的配置方法
java
计算机毕设指导61 天前
基于SpringBoot校园学生健康监测管理系统【源码文末联系】
java·spring boot·后端·spring·tomcat·maven·intellij-idea
RInk7oBjo1 天前
spring-事务管理
数据库·sql·spring
mysuking1 天前
springboot与springcloud对应版本
java·spring boot·spring cloud
希望永不加班1 天前
SpringBoot 数据库连接池配置(HikariCP)最佳实践
java·数据库·spring boot·后端·spring