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

Cookie过期自动跳转登录页失效,如何排查并禁用滑动过期

问题描述

我想实现用户Cookie过期时页面自动跳转到登录页的功能,目前用页面JS定时检查+后端中间件验证用户是否认证,但功能没生效。推测问题是Cookie仍在触发滑动过期机制,请问如何排查该问题,以及让检查请求不触发Cookie的滑动过期?

现有代码

后端配置与中间件(C#)

builder.Services.ConfigureApplicationCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    options.LoginPath = "/Identity/Account/Login";
    options.SlidingExpiration = true;
});

app.UseMiddleware<SessionExpiryCheckMiddleware>();

public class SessionExpiryCheckMiddleware
{
    private readonly RequestDelegate _next;

    public SessionExpiryCheckMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // Only check session for specific paths
        if (context.Request.Path.StartsWithSegments("/SessionStatus"))
        {
            var isAuthenticated = context.User.Identity.IsAuthenticated;

            // If user is authenticated, proceed without extending session
            if (!isAuthenticated)
            {
                // Invalidate session
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                return;
            }
        }

        await _next(context);
    }
}

前端定时检查代码(JavaScript)

setInterval(function () {
    fetch('/SessionStatus', {
        method: 'GET',
        credentials: 'same-origin'
    })
        .then(response => {
            console.log(response.status);
            if (response.status === 401) {
                // Session has expired, redirect to login page
                window.location.href = '/Identity/Account/Login';
            }
        })
        .catch(error => {
            console.error('Error checking session status:', error);
        });
}, 5000);
排查方案与解决方法

一、排查滑动过期是否真的被触发

  • 浏览器端验证:打开F12开发者工具→Application标签→找到对应域名下的.AspNetCore.Identity.ApplicationCookie,记录其Expires/Max-Age时间。等待1分钟后触发一次/SessionStatus请求,再查看该Cookie的过期时间是否被延后5分钟(与你设置的ExpireTimeSpan一致),如果是则说明滑动过期确实被触发。
  • 后端日志验证:在appsettings.json中开启认证Cookie的Debug级别日志,查看每次请求/SessionStatus时是否有滑动更新票据的日志:
    "Logging": {
      "LogLevel": {
        "Microsoft.AspNetCore.Authentication.Cookies": "Debug"
      }
    }
    
    日志中若出现类似“滑动刷新了认证票据”的条目,即可确认滑动过期被触发。

二、让检查请求不触发滑动过期

ASP.NET Core的Cookie认证中间件默认会对携带有效认证Cookie的请求触发滑动过期(当SlidingExpiration=true时),需要通过认证事件跳过检查请求的滑动更新:

builder.Services.ConfigureApplicationCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    options.LoginPath = "/Identity/Account/Login";
    options.SlidingExpiration = true;
    options.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = context =>
        {
            // 针对会话检查请求,禁止滑动更新Cookie
            if (context.Request.Path.StartsWithSegments("/SessionStatus"))
            {
                context.ShouldRenew = false;
            }
            return Task.CompletedTask;
        }
    };
});

三、优化中间件逻辑

现有中间件在用户已认证时会继续执行后续中间件,可直接返回200状态码减少不必要的处理:

public async Task Invoke(HttpContext context)
{
    if (context.Request.Path.StartsWithSegments("/SessionStatus"))
    {
        var isAuthenticated = context.User.Identity.IsAuthenticated;
        if (!isAuthenticated)
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        }
        else
        {
            // 已认证直接返回200,无需走后续中间件
            context.Response.StatusCode = StatusCodes.Status200OK;
        }
        return;
    }

    await _next(context);
}

四、其他失效原因排查

  • 确认浏览器未禁用Cookie,且Cookie的Secure/SameSite设置与当前环境匹配(HTTPS环境需开启Secure=true,否则Cookie不会被发送)。
  • 检查JS的fetch请求是否正确携带Cookie:credentials: 'same-origin'配置正确,但需确保/SessionStatus与当前页面同域。
  • 确认ExpireTimeSpan配置未被其他代码覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:34:57