You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 前端实现

核心逻辑:监听用户交互,启动双计时器——一个用于触发超时前警告,一个用于执行最终超时操作;用户有操作时重置所有计时器。

  1. 封装会话超时管理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;
  1. 在主应用组件中使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:15:02