Spring Boot+React单页应用会话超时/重启后重定向至登录页方案
简易实现思路:Spring Boot + React 会话超时/应用重启自动重定向登录页
嘿,我之前在做类似的Spring Boot + React项目时也碰到过这个需求,给你几个低成本、易实现的方案,分前后端配合来搞定:
后端(Spring Boot + Spring Security)处理
首先从后端层面做好会话失效的标识和配置:
- 配置会话超时与失效跳转:
在application.properties里设置会话超时时间(比如30分钟):
然后在Spring Security的配置类里,指定会话失效后的跳转目标,同时处理未认证的请求:server.servlet.session.timeout=30m server.servlet.session.tracking-modes=cookie@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .formLogin(form -> form .loginPage("/login") .permitAll() ) .sessionManagement(session -> session .invalidSessionUrl("/login") // 会话失效时跳转登录页 .maximumSessions(1) // 可选:限制单用户登录 .expiredUrl("/login?expired=true") // 会话过期带标识 ); return http.build(); } } - 全局异常处理返回401:
给后端接口加个全局异常处理器,当捕获到会话过期、未认证的异常时,统一返回401状态码,方便前端识别:@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler({AuthenticationException.class, SessionExpiredException.class}) public ResponseEntity<Void> handleAuthExceptions() { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } }
前端(React)处理
前端主要做两件事:拦截接口异常、主动检查会话状态:
- Axios响应拦截器统一处理401:
项目里如果用Axios做请求工具,加个响应拦截器,一旦收到401状态码,立刻清除本地存储的用户信息(比如token、用户数据),然后跳转到登录页:import axios from 'axios'; // 全局Axios实例配置 const axiosInstance = axios.create({ baseURL: '/api', }); axiosInstance.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { // 清除本地存储的用户数据 localStorage.removeItem('userToken'); localStorage.removeItem('userInfo'); // 跳转到登录页 window.location.href = '/login'; } return Promise.reject(error); } ); export default axiosInstance; - 主动检查会话状态(可选但更及时):
可以做两个补充检查,避免用户长时间后台挂起或应用重启后未察觉:- 定时检查:每隔10分钟调用一个轻量接口(比如后端写个
/api/check-session,仅返回状态码),如果返回401就跳转登录页。 - 页面可见性监听:当页面从后台切换到前台时,立刻调用检查接口:
import { useEffect } from 'react'; import axiosInstance from './axiosInstance'; const useSessionChecker = () => { useEffect(() => { const checkSession = async () => { try { await axiosInstance.get('/api/check-session'); } catch (err) { if (err.response?.status === 401) { localStorage.clear(); window.location.href = '/login'; } } }; // 页面切回前台时检查 const handleVisibilityChange = () => { if (!document.hidden) { checkSession(); } }; document.addEventListener('visibilitychange', handleVisibilityChange); // 定时检查,每10分钟一次 const interval = setInterval(checkSession, 10 * 60 * 1000); return () => { document.removeEventListener('visibilitychange', handleVisibilityChange); clearInterval(interval); }; }, []); }; export default useSessionChecker;
- 定时检查:每隔10分钟调用一个轻量接口(比如后端写个
这样不管是会话超时还是Spring Boot应用重启(重启后所有会话失效,前端请求会返回401),都能自动跳转到登录页,而且实现起来都是基础配置和代码,不需要引入额外复杂的依赖~
内容的提问来源于stack exchange,提问作者Hagar Tal
相关产品推荐
相关产品推荐

