You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:23:16