ASP.NET Core Razor应用:闲置10分钟及关闭浏览器时清除ISession
实现ASP.NET Core Razor应用中两种场景的会话清除
一、会话闲置10分钟自动清除
ASP.NET Core的ISession原生支持配置闲置超时,结合Cookie配置即可实现基础的超时清除逻辑,还可扩展主动清理关联业务资源的逻辑。
1. 配置Session与Cookie
在Program.cs中设置Session的闲置超时时间,并配置安全的Cookie属性:
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(10); // 闲置10分钟后会话过期 options.Cookie.HttpOnly = true; // 禁止前端脚本访问Cookie,提升安全性 options.Cookie.IsEssential = true; // 标记为必要Cookie,适配隐私合规要求 // 不设置Cookie.Expires,保持默认会话Cookie特性(浏览器关闭即失效) }); // 注册Session中间件(需放在UseRouting之后、UseEndpoints之前) app.UseSession();
2. 主动清理关联资源(可选)
服务器会自动标记超时会话为过期,但如果需要同步清理用户关联的缓存或业务数据,可在请求流程中检查会话的最后活动时间:
先实现Session扩展方法,用于存储和读取最后活动时间:
public static class SessionExtensions { public static void SetLastActivity(this ISession session, DateTime timestamp) { session.SetString("LastActivity", timestamp.ToString("o")); } public static DateTime? GetLastActivity(this ISession session) { var value = session.GetString("LastActivity"); return value == null ? null : DateTime.Parse(value); } }
然后在Razor页面的请求处理方法中检查并清理:
public class IndexModel : PageModel { public void OnGet() { var lastActivity = HttpContext.Session.GetLastActivity(); if (lastActivity.HasValue && lastActivity.Value.AddMinutes(10) < DateTime.UtcNow) { // 清除当前会话数据 HttpContext.Session.Clear(); // 清理用户关联的其他资源(如分布式缓存中的用户业务数据) var cache = HttpContext.RequestServices.GetRequiredService<IDistributedCache>(); cache.Remove($"UserBusinessData:{HttpContext.Session.Id}"); } // 更新最后活动时间为当前UTC时间 HttpContext.Session.SetLastActivity(DateTime.UtcNow); } }
二、用户未登出关闭所有浏览器标签页时清除会话
默认情况下,Session Cookie是会话级别的,关闭浏览器后Cookie会被删除,但服务器端的会话数据仍会保留到闲置超时。要实现即时清除,需结合前端卸载事件与后端清理接口。
1. 前端监听页面卸载事件
在Razor页面中添加脚本,使用navigator.sendBeacon发送异步清理请求(该方法不会阻塞页面卸载,兼容性更优):
<script> window.addEventListener('beforeunload', (event) => { // 判断是否为关闭浏览器/标签页操作(排除刷新、跳转等场景) const isClosing = event.clientY < 0 || event.clientX < 0 || event.altKey || event.ctrlKey || event.metaKey; if (isClosing) { // 发送会话清理请求 navigator.sendBeacon('/ClearSession', JSON.stringify({ sessionId: '@Context.Session.Id' })); } }); </script>
2. 后端实现会话清理端点
创建ClearSession.cshtml.cs页面模型,处理前端发送的清理请求:
public class ClearSessionModel : PageModel { private readonly IDistributedCache _cache; public ClearSessionModel(IDistributedCache cache) { _cache = cache; } public async Task<IActionResult> OnPostAsync() { using var reader = new StreamReader(Request.Body); var body = await reader.ReadToEndAsync(); var requestData = System.Text.Json.JsonSerializer.Deserialize<SessionClearRequest>(body); if (!string.IsNullOrEmpty(requestData?.SessionId) && HttpContext.Session.Id == requestData.SessionId) { // 清除当前会话数据 HttpContext.Session.Clear(); // 移除分布式缓存中的会话项(若使用Redis等分布式缓存) await _cache.RemoveAsync($"Session:{requestData.SessionId}"); } return new OkResult(); } private class SessionClearRequest { public string SessionId { get; set; } } }
注意:该方法无法保证100%可靠(如浏览器崩溃、网络中断时请求可能无法送达),因此服务器端的闲置超时配置仍需作为兜底方案。
内容的提问来源于stack exchange,提问作者Chhotelal Gupta




