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

Blazor WebAssembly如何通过Cookie实现用户会话持久化?

Blazor WebAssembly 完全可以通过带到期时间的 Cookie 持久化用户会话,以下是具体实现方案和注意事项:

默认会话存储的问题

Blazor WASM 官方的 OIDC 认证组件默认使用 sessionStorage 存储用户令牌、身份信息,该存储的生命周期和浏览器标签页绑定,关闭标签页/浏览器后数据就会自动清除,因此无法实现跨会话的登录态保留。
你当前的配置已经包含了 offline_access 权限,且 IdentityServer 令牌有效期设置为 30 天,只需要替换默认的存储实现就能实现需求。

因为 Blazor WASM 运行在浏览器沙箱中,无法直接操作 Cookie,需要通过 JS Interop 完成读写,步骤如下:

  1. 实现自定义 IUserStore 替换默认存储
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.JSInterop;
using System.Text.Json;

public class CookieUserStore : IUserStore<RemoteUserAccount>
{
    private readonly IJSRuntime _jsRuntime;

    public CookieUserStore(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    public async Task<RemoteUserAccount?> GetUserAsync()
    {
        var accountJson = await _jsRuntime.InvokeAsync<string>("getCookie", "blazor_auth_session");
        return string.IsNullOrWhiteSpace(accountJson) 
            ? null 
            : JsonSerializer.Deserialize<RemoteUserAccount>(accountJson);
    }

    public async Task SetUserAsync(RemoteUserAccount? user)
    {
        if (user == null)
        {
            await _jsRuntime.InvokeVoidAsync("deleteCookie", "blazor_auth_session");
            return;
        }
        var accountJson = JsonSerializer.Serialize(user);
        // Cookie有效期和IdentityServer令牌有效期对齐,设为30天
        await _jsRuntime.InvokeVoidAsync("setCookie", "blazor_auth_session", accountJson, 30);
    }
}
  1. 注册自定义存储
    修改你的启动配置,替换默认的用户存储:
builder.Services.AddOidcAuthentication(options =>
{
    builder.Configuration.Bind("Local", options.ProviderOptions);
    options.UserOptions.RoleClaim = "RoleName";
})
// 注入自定义Cookie存储
.AddUserStore<CookieUserStore>();
  1. 添加 Cookie 操作的 JS 方法
    在 wwwroot/index.html 中加入以下脚本:
// 写入Cookie
function setCookie(name, value, expireDays) {
    const date = new Date();
    date.setTime(date.getTime() + expireDays * 24 * 60 * 60 * 1000);
    const expires = `expires=${date.toUTCString()}`;
    document.cookie = `${name}=${encodeURIComponent(value)};${expires};path=/;SameSite=Strict;Secure`;
}

// 读取Cookie
function getCookie(name) {
    const cookieArr = document.cookie.split('; ');
    for (let item of cookieArr) {
        const [key, val] = item.split('=');
        if (key === name) return decodeURIComponent(val);
    }
    return '';
}

// 删除Cookie
function deleteCookie(name) {
    document.cookie = `${name}=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT;SameSite=Strict;Secure`;
}

注意事项

  • 单条 Cookie 最大存储容量为 4KB,如果你的身份令牌、声明信息较大超过该限制,推荐改用 localStorage 实现持久化,实现逻辑和上面完全一致,只需要把 JS 中的 Cookie 操作改为 localStorage.setItem/getItem 即可。
  • 存储在客户端的令牌存在 XSS 窃取风险,需做好全站 XSS 防护:对所有用户输入做转义处理、禁止执行不可信的第三方脚本。
  • 你配置的 offline_access scope 会自动获取刷新令牌,当 access_token 过期时,OIDC 组件会自动用刷新令牌向 IdentityServer 申请新的令牌,无需用户重新登录,完全匹配你30天有效期的需求。
  • 如果你的 Blazor WASM 是 ASP.NET Core 托管模式部署,更推荐将令牌存储在后端的 HttpOnly Cookie 中,由后端代理转发 API 请求时携带令牌,彻底避免客户端令牌泄露风险。

内容的提问来源于stack exchange,提问作者Luís Antunes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 01:09:02