.NET9 Blazor Server单体应用用户登录及跨页数据读取的正确方法
在.NET9 Blazor Server单体应用中保存用户登录状态的简洁方案
针对你不想使用SignInManager<TUser>的需求,可以通过Cookie认证体系的基础API实现简洁的登录状态保存与读取,以下是具体步骤:
1. 配置Cookie认证服务
首先在Program.cs中配置认证与授权服务,确保中间件顺序正确:
// 添加Cookie认证服务 builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/Login"; // 未登录时的跳转路径 options.ExpireTimeSpan = TimeSpan.FromDays(7); // Cookie有效期 options.SlidingExpiration = true; // 启用滑动过期(用户活跃时自动延长有效期) }); // 添加授权服务 builder.Services.AddAuthorization(); // 中间件顺序必须是:Authentication → Authorization app.UseAuthentication(); app.UseAuthorization();
2. 实现登录逻辑(保存用户声明)
无需依赖复杂的Identity组件,只需注入IAuthenticationService和IHttpContextAccessor即可完成登录:
- 确保引用正确的NuGet包:
Microsoft.AspNetCore.Authentication.Cookies(这是.NET9中维护的官方包,并非过时的旧版本)。 - 在登录服务/组件中注入服务并实现登录:
private readonly IAuthenticationService _authService; private readonly IHttpContextAccessor _httpContextAccessor; // 构造函数注入 public LoginHandler(IAuthenticationService authService, IHttpContextAccessor httpContextAccessor) { _authService = authService; _httpContextAccessor = httpContextAccessor; } public async Task<bool> ValidateAndLoginAsync(string username, string password) { // 第一步:验证数据库中的凭证(自行实现用户名密码校验逻辑) bool isCredentialValid = await ValidateCredentialsFromDb(username, password); if (!isCredentialValid) return false; // 第二步:创建用户声明与身份主体 var claims = new List<Claim> { new Claim(ClaimTypes.Name, username), // 可添加其他声明,如角色、权限等 new Claim(ClaimTypes.Role, "User") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); // 第三步:保存登录状态到Cookie await _authService.SignInAsync( _httpContextAccessor.HttpContext!, CookieAuthenticationDefaults.AuthenticationScheme, principal ); return true; }
3. 跨页面读取登录状态
在Blazor组件中,有两种简洁的方式读取用户登录信息:
方式一:使用AuthenticationStateProvider
@inject AuthenticationStateProvider AuthStateProvider <div> @if (_isAuthenticated) { <p>当前登录用户:@_userName</p> } else { <p>未登录</p> } </div> @code { private bool _isAuthenticated; private string? _userName; protected override async Task OnInitializedAsync() { var authState = await AuthStateProvider.GetAuthenticationStateAsync(); var user = authState.User; _isAuthenticated = user.Identity?.IsAuthenticated == true; if (_isAuthenticated) { _userName = user.Identity.Name; // 读取其他声明示例 var userRole = user.FindFirst(ClaimTypes.Role)?.Value; } } }
方式二:使用<AuthorizeView>组件(更简洁的UI控制)
<AuthorizeView> <Authorized> <div>欢迎,@context.User.Identity.Name!</div> <!-- 已登录用户可见的内容 --> </Authorized> <NotAuthorized> <div>请先登录</div> <!-- 未登录用户可见的内容 --> </NotAuthorized> </AuthorizeView>
关于你之前遇到的问题说明
- 直接调用
HttpContext.SignInAsync报错:该方法已从HttpContext实例移至IAuthenticationService的扩展方法,需通过注入的服务调用。 - 旧
Microsoft.AspNetCore.Authentication包过时:该包是.NET Core早期版本的聚合包,.NET3.0+已拆分为细分包,使用Microsoft.AspNetCore.Authentication.Cookies即可。 AuthenticationManager.SignInAsync过时:这是Blazor WebAssembly的旧API,Blazor Server不适用。
内容的提问来源于stack exchange,提问作者Val
相关产品推荐
相关产品推荐

