ASP.NET中如何通过Cookie实现封禁用户时强制其下线?
你当前使用的Cookie认证逻辑默认签发后服务端不会二次校验有效性,直到Cookie自然过期,所以需要追加实时身份有效性校验逻辑,具体实现步骤如下:
1. 配置Cookie认证的校验事件
在服务注册阶段添加Cookie认证时,注册OnValidatePrincipal事件,该事件会在每个携带有效Cookie的请求进入时触发,用于校验当前用户身份是否仍然有效:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { // 保留你原有Cookie配置项,仅追加如下事件逻辑 options.Events.OnValidatePrincipal = async context => { // 从当前身份凭证中读取你存入的用户唯一标识邮箱 var userEmail = context.Principal?.FindFirstValue(ClaimTypes.Email); if (string.IsNullOrEmpty(userEmail)) { // 身份信息无效直接拒绝并登出 context.RejectPrincipal(); await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return; } // 从缓存中查询该用户是否已经被封禁 var cache = context.HttpContext.RequestServices.GetRequiredService<IDistributedCache>(); var banFlag = await cache.GetStringAsync($"BannedUser:{userEmail}"); if (!string.IsNullOrEmpty(banFlag)) { // 匹配到封禁标记,强制登出 context.RejectPrincipal(); await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); } }; });
如果是单实例小项目,也可以将IDistributedCache替换为IMemoryCache使用内存缓存,无需额外部署缓存中间件。
2. 封禁用户时写入封禁标记
执行封禁用户操作的逻辑中,追加写入缓存的逻辑,缓存过期时间和你设置的Cookie最大有效期保持一致即可,避免缓存冗余:
// 封禁用户逻辑中追加 await _distributedCache.SetStringAsync($"BannedUser:{待封禁用户邮箱}", "1", new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(7) // 与你的Cookie有效期匹配即可 });
如果需要解除用户封禁,直接删除对应缓存key即可恢复用户登录状态。
可选优化
如果担心每次请求都查询缓存影响性能,可以在登录时给Claims追加LastLoginTime声明,校验时先判断Cookie签发时间是否早于封禁记录的更新时间,再触发缓存查询,也可以增加本地二级缓存降低缓存查询开销。
内容的提问来源于stack exchange,提问作者balimka
相关产品推荐
相关产品推荐

