.NET 5项目如何实现调用不刷新身份验证Cookie的API端点
解答
结论
完全可以实现,只需要对现有逻辑做少量调整即可。
原理说明
ASP.NET Core Cookie身份验证的滑动过期触发逻辑为:当请求携带有效的身份票据,且票据剩余有效期不足总有效期的1/2时,中间件会自动生成新的票据并下发新Cookie完成续期。我们只需要让IsAuthenticated接口跳过该续期逻辑即可。
现有代码问题
你当前的代码已经可以正确返回用户登录状态,但接口请求仍会触发默认的滑动续期逻辑,不符合要求。
实现方案
方案1:全局配置跳过指定接口续期(推荐)
修改Startup.cs中的Cookie认证配置,新增OnValidatePrincipal事件拦截指定接口的续期行为:
services.AddAuthentication() .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, config => { config.LoginPath = "/Account/Login"; config.AccessDeniedPath = "/Account/NoAccess"; config.ExpireTimeSpan = TimeSpan.FromSeconds(settings.CookieSlidingExpirationInSeconds); config.SlidingExpiration = true; // 新增下面的事件配置 config.Events.OnValidatePrincipal = context => { // 匹配校验登录状态的接口路径,禁止该接口触发续期 if (context.Request.Path.StartsWithSegments("/Login/IsAuthenticated", StringComparison.OrdinalIgnoreCase)) { context.ShouldRenew = false; } return Task.CompletedTask; }; });
该方案无需修改接口代码,侵入性极低,同时保留原有的身份校验逻辑,稳定性更高。
方案2:手动解析Cookie票据(无全局配置侵入)
如果不想修改全局Cookie配置,可以直接在接口内手动解析Cookie判断登录状态,完全不触发中间件的续期逻辑:
- 首先在控制器注入依赖:
private readonly IAuthenticationSchemeProvider _schemeProvider; private readonly IDataProtectionProvider _dataProtectionProvider; public LoginController(IAuthenticationSchemeProvider schemeProvider, IDataProtectionProvider dataProtectionProvider) { _schemeProvider = schemeProvider; _dataProtectionProvider = dataProtectionProvider; }
- 修改接口实现:
[HttpGet] [AllowAnonymous] public async Task<IActionResult> IsAuthenticated() { bool isAuthenticated = false; var cookie = Request.Cookies[CookieAuthenticationDefaults.CookiePrefix + CookieAuthenticationDefaults.AuthenticationScheme]; if (!string.IsNullOrEmpty(cookie)) { try { var scheme = await _schemeProvider.GetSchemeAsync(CookieAuthenticationDefaults.AuthenticationScheme); var protector = _dataProtectionProvider.CreateProtector(scheme.HandlerType, CookieAuthenticationDefaults.AuthenticationScheme); var ticket = TicketDataFormat.Default.Unprotect(protector, cookie); isAuthenticated = ticket?.Principal?.Identity?.IsAuthenticated == true && ticket.Properties.ExpiresUtc > DateTimeOffset.UtcNow; } catch { // 解密失败说明Cookie无效,不做处理 } } return Ok(new { IsAuthenticated = isAuthenticated }); }
验证方式
调整完成后可以通过浏览器调试工具观察Set-Cookie响应头:正常请求其他受保护接口时会在需要续期时返回该头,请求IsAuthenticated接口时无论Cookie剩余有效期多久都不会返回Set-Cookie头,即符合要求。
内容的提问来源于stack exchange,提问作者erik_nw
相关产品推荐
相关产品推荐

