Blazor WASM自定义AuthenticationStateProvider获取SessionId Cookie问题
在 Blazor WASM 中,客户端本身没有 HttpContext,无法直接读取 Cookie,但你可以通过以下纯 Blazor 原生方案实现需求,无需依赖 JSRuntime:
核心思路
利用 Blazor WASM 集成的 HttpClient,它默认会自动携带浏览器当前域的 Cookie(基于浏览器的 Cookie 存储机制)。你只需在后端提供一个接口,该接口读取请求中的 sessionId Cookie,返回对应用户的认证信息,然后在自定义 AuthenticationStateProvider 中调用这个接口,构建并返回 AuthenticationState。
具体实现
1. 自定义 AuthenticationStateProvider 实现
public class CustomAuthStateProvider : AuthenticationStateProvider { private readonly HttpClient _httpClient; private ClaimsPrincipal _cachedUser; public CustomAuthStateProvider(HttpClient httpClient) { _httpClient = httpClient; } public override async Task<AuthenticationState> GetAuthenticationStateAsync() { // 缓存认证状态,避免每次页面访问都请求后端 if (_cachedUser != null) { return new AuthenticationState(_cachedUser); } try { // 调用后端接口获取当前用户信息,接口会自动携带 sessionId Cookie var userInfo = await _httpClient.GetFromJsonAsync<UserInfo>("/api/auth/currentuser"); if (userInfo != null && !string.IsNullOrEmpty(userInfo.UserId)) { var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, userInfo.UserId), new Claim(ClaimTypes.Name, userInfo.Username) // 根据业务需求添加其他 Claim }; var identity = new ClaimsIdentity(claims, "SessionAuthentication"); _cachedUser = new ClaimsPrincipal(identity); } else { // 无有效会话,返回匿名用户 _cachedUser = new ClaimsPrincipal(new ClaimsIdentity()); } } catch (HttpRequestException) { // 请求失败时默认返回匿名用户 _cachedUser = new ClaimsPrincipal(new ClaimsIdentity()); } return new AuthenticationState(_cachedUser); } // 登录/登出后手动更新认证状态的方法 public void RefreshAuthenticationState(ClaimsPrincipal updatedUser) { _cachedUser = updatedUser; NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(updatedUser))); } } // 后端返回的用户信息模型 public class UserInfo { public string UserId { get; set; } public string Username { get; set; } // 其他需要的用户属性 }
2. 后端接口实现(ASP.NET Core 示例)
[ApiController] [Route("api/auth")] public class AuthApiController : ControllerBase { private readonly ISessionManager _sessionManager; public AuthApiController(ISessionManager sessionManager) { _sessionManager = sessionManager; } [HttpGet("currentuser")] public async Task<IActionResult> GetCurrentUser() { // 从请求中读取 sessionId Cookie var sessionId = Request.Cookies["sessionId"]; if (string.IsNullOrEmpty(sessionId)) { return Ok(null); } // 根据 sessionId 获取对应的用户信息 var user = await _sessionManager.GetUserBySessionId(sessionId); if (user == null) { return Ok(null); } return Ok(new UserInfo { UserId = user.Id.ToString(), Username = user.Username }); } }
3. 注册自定义 Provider
在 Program.cs 中注册你的自定义认证状态提供者:
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
补充说明
HttpClient自动携带 Cookie:Blazor WASM 的HttpClient基于浏览器的 Fetch API,默认会自动发送当前域下的所有 Cookie,无需额外配置。- 缓存优化:通过
_cachedUser缓存认证状态,避免每次页面访问都发起后端请求,提升性能。在登录/登出操作完成后,调用RefreshAuthenticationState方法主动刷新状态即可。
内容的提问来源于stack exchange,提问作者Jan Safronov
相关产品推荐
相关产品推荐

