Blazor Server Side应用多用户登录串号、会话互串问题咨询
问题核心原因
你遇到的是Blazor Server应用典型的全局状态共享问题,和Blazor Server的运行机制、依赖注入生命周期直接相关,常见的错误实现有三类:
- 服务注册时使用了错误的生命周期:Blazor Server的依赖注入包含三种默认生命周期:
Singleton(单例,全应用所有用户共享同一个实例)、Scoped(作用域,Blazor Server中对应单个用户的SignalR连接生命周期,单用户独享)、Transient(瞬态,每次请求创建新实例)。如果你把存储当前登录用户信息的服务注册为Singleton,所有用户都会读写同一个用户数据对象,自然会出现跨用户串数据、登出互相影响的问题。 - 使用静态字段/属性存储用户登录状态:C#中的静态变量属于应用级全局共享资源,不会随用户连接变化,只要把当前登录用户ID、资料等信息存在静态成员中,所有用户都会访问到同一份数据。
- 自定义
AuthenticationStateProvider时错误注册为单例:ASP.NET Core自带的身份验证状态提供器默认是Scoped生命周期,如果你自行实现了自定义的身份验证状态逻辑,且手动将其注册为Singleton,也会导致所有用户共享同一份登录状态。
修复方案
- 调整存储用户状态的服务的生命周期,统一注册为
Scoped:在Program.cs中修改服务注册代码,例如把原本的builder.Services.AddSingleton<IUserService, UserService>();修改为builder.Services.AddScoped<IUserService, UserService>(); - 移除存储用户登录态的静态字段/属性,所有用户相关的临时状态都通过
Scoped服务或者Blazor组件的状态来存储。 - 确保自定义的
AuthenticationStateProvider注册为Scoped:注册代码应为builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();,不要改为单例注册。 - 校验逻辑调整:所有需要读取当前登录用户信息的场景,优先通过注入
AuthenticationStateProvider获取当前请求的用户Claims,再从数据库拉取对应用户的资料,不要直接读全局共享的用户对象。
内容的提问来源于stack exchange,提问作者M-Corp
相关产品推荐
相关产品推荐

