ASP.NET Core + React 会话超时提前通知功能实现求助
ASP.NET Core + React 会话超时前通知实现方案
一、ASP.NET Core 后端配置
- 首先在
Program.cs中配置会话超时参数,同时启用会话中间件:builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(20); // 自定义会话超时总时长 options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // 注意:必须放在app.UseRouting()之后 app.UseSession(); - 提供接口用于前端获取会话超时时长,或支持会话刷新:
[ApiController] [Route("api/session")] public class SessionController : ControllerBase { // 返回会话超时总时长(秒) [HttpGet("timeout")] public IActionResult GetTimeout() { var totalSeconds = HttpContext.Session.IdleTimeout.TotalSeconds; return Ok(new { timeoutSeconds = totalSeconds }); } // 刷新会话(用户点击"继续会话"时调用) [HttpGet("refresh")] public IActionResultRefresh() { // 通过修改会话内容触发超时重置 HttpContext.Session.SetString("LastActive", DateTime.UtcNow.ToString()); return Ok(); } }
二、React 前端实现
核心逻辑:监听用户交互,启动双计时器——一个用于触发超时前警告,一个用于执行最终超时操作;用户有操作时重置所有计时器。
- 封装会话超时管理Hook
import { useEffect, useRef, useState } from 'react'; const useSessionTimeout = (timeoutSeconds = 1200, warningSeconds = 60) => { const [showWarning, setShowWarning] = useState(false); const warningTimer = useRef(null); const timeoutTimer = useRef(null); // 重置所有计时器 const resetTimers = () => { setShowWarning(false); clearTimeout(warningTimer.current); clearTimeout(timeoutTimer.current); // 超时前warningSeconds触发警告 warningTimer.current = setTimeout(() => { setShowWarning(true); }, (timeoutSeconds - warningSeconds) * 1000); // 超时后执行登出逻辑 timeoutTimer.current = setTimeout(() => { window.location.href = '/login'; }, timeoutSeconds * 1000); }; // 监听用户交互事件 useEffect(() => { // 初始化计时器 resetTimers(); const handleUserActivity = () => resetTimers(); window.addEventListener('click', handleUserActivity); window.addEventListener('keydown', handleUserActivity); // 组件卸载时清理 return () => { window.removeEventListener('click', handleUserActivity); window.removeEventListener('keydown', handleUserActivity); clearTimeout(warningTimer.current); clearTimeout(timeoutTimer.current); }; }, [timeoutSeconds, warningSeconds]); // 处理"继续会话"点击 const handleContinue = async () => { try { await fetch('/api/session/refresh'); resetTimers(); } catch (err) { console.error('刷新会话失败:', err); } }; return { showWarning, handleContinue }; }; export default useSessionTimeout;
- 在主应用组件中使用Hook
import useSessionTimeout from './hooks/useSessionTimeout'; function App() { // 可从后端接口获取实际超时时长,这里默认20分钟超时、提前1分钟警告 const { showWarning, handleContinue } = useSessionTimeout(1200, 60); return ( <div className="app-container"> {/* 应用主体内容 */} {showWarning && ( <div className="session-warning-modal"> <p>您的会话将在1分钟后过期</p> <button onClick={handleContinue}>继续会话</button> </div> )} </div> ); } export default App;
三、关键注意事项
- 保持会话Cookie的
HttpOnly为true,避免前端直接操作Cookie引发安全风险,超时时长通过后端接口获取。 - 如果使用JWT令牌而非内置会话,需调整为解析JWT的
exp字段计算超时时间,刷新逻辑替换为获取新令牌。 - 测试时可缩短超时时长(如设置为2分钟),快速验证功能有效性。
内容的提问来源于stack exchange,提问作者Andrii Novosad
相关产品推荐
相关产品推荐

