You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Spring Boot中实现基础用户认证及持久化登录状态?

搞定简单的持久化登录+全局用户名显示,不用被重型框架吓倒!

兄弟我太懂你这种感受了——Spring Security、Shiro这类框架确实封装得太厚重,当你只需要「登录一次、全局显名、超时自动登出」这种基础需求时,看着一堆配置项简直头大。其实不用纠结复杂框架,不管是纯手写轻量实现,还是简化框架配置,都能轻松搞定你要的功能,我给你拆解一下:

一、纯手写轻量实现(完全不用框架)

如果你不想碰那些重型框架,自己写几行代码就能搞定核心逻辑:

  • 登录接口处理
    验证用户名密码通过后,创建一个Cookie,把用户名(或者加密后的用户标识)存进去,关键配置要做好:

    Cookie authCookie = new Cookie("user_auth", "你的用户名");
    authCookie.setHttpOnly(true); // 防止JS读取,防XSS攻击
    authCookie.setSecure(true); // 生产环境开启,只在HTTPS下传输
    authCookie.setMaxAge(7 * 24 * 60 * 60); // 7天过期,直接控制登录时长
    authCookie.setPath("/"); // 全站有效,所有页面都能拿到这个Cookie
    response.addCookie(authCookie);
    

    (如果要更安全,可以把用户名加密后存,或者存用户ID,后端再查数据库取用户名,避免Cookie被恶意篡改)

  • 全局拦截用户信息
    写一个拦截器/过滤器,在所有请求进来时,读取这个Cookie并传递给页面:

    String username = null;
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if ("user_auth".equals(cookie.getName())) {
                username = cookie.getValue();
                // 如果存的是加密内容,这里要先解密
                break;
            }
        }
    }
    // 把用户名放到请求属性里,模板引擎能直接读取
    request.setAttribute("currentUsername", username);
    
  • 页面显示用户名
    用你正在用的模板引擎(比如Thymeleaf、JSP)在页面导航栏或头部直接渲染:

    <!-- Thymeleaf示例 -->
    <div class="nav-bar">
        欢迎回来, <span th:text="${currentUsername}"></span>
    </div>
    
  • 登出功能
    只需要把这个Cookie的过期时间设为0,浏览器就会自动删除它:

    Cookie authCookie = new Cookie("user_auth", "");
    authCookie.setMaxAge(0);
    authCookie.setPath("/");
    response.addCookie(authCookie);
    

二、简化Spring Security配置(不想放弃框架但嫌复杂)

如果还是想用Spring Security,但不想搞那些复杂的权限控制,只保留你需要的核心功能:

  • 极简配置类
    只开启表单登录,关闭不必要的功能,配置会话超时:

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
            http
                .authorizeHttpRequests(auth -> auth
                    .anyRequest().permitAll() // 暂时放开所有请求,按需调整权限
                )
                .formLogin(form -> form
                    .loginPage("/login") // 自定义登录页路径
                    .defaultSuccessUrl("/") // 登录成功后跳转首页
                )
                .logout(logout -> logout
                    .logoutSuccessUrl("/login") // 登出后跳转登录页
                )
                .sessionManagement(session -> session
                    .sessionFixation().migrateSession()
                    .invalidSessionUrl("/login") // 会话过期后跳转登录页
                    .maximumSessions(1) // 限制单用户只能登录一次
                    .expiredUrl("/login")
                )
                .csrf(csrf -> csrf.disable()); // 简单场景可先关闭,生产环境建议开启
    
            return http.build();
        }
    
        @Bean
        public AuthenticationProvider authenticationProvider() {
            DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
            authProvider.setUserDetailsService(userDetailsService);
            authProvider.setPasswordEncoder(passwordEncoder());
            return authProvider;
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
  • 页面直接取用户名
    用Spring Security的专属表达式,不用自己处理Cookie:

    <!-- Thymeleaf + Spring Security示例 -->
    <div class="nav-bar">
        欢迎回来, <span sec:authentication="name"></span>
    </div>
    
  • 控制登录时长
    application.properties里配置会话过期时间:

    server.servlet.session.timeout=7d # 7天过期
    server.servlet.session.cookie.http-only=true
    server.servlet.session.cookie.secure=true
    

几个关键提醒

  • 安全优先:Cookie一定要加HttpOnly,生产环境开启Secure;如果存敏感信息,建议加密或者用带签名的JWT,防止篡改。
  • 会话存储:小项目用服务器内存存会话没问题;如果用户量大,建议用Redis存会话,避免内存溢出。
  • 不要过度设计:你要的核心功能其实很简单,不用硬套复杂框架的所有功能,按需取舍就好。

内容的提问来源于stack exchange,提问作者rococo

火山引擎 最新活动