Blazor WebAssembly如何通过Cookie实现用户会话持久化?
Blazor WebAssembly 完全可以通过带到期时间的 Cookie 持久化用户会话,以下是具体实现方案和注意事项:
默认会话存储的问题
Blazor WASM 官方的 OIDC 认证组件默认使用 sessionStorage 存储用户令牌、身份信息,该存储的生命周期和浏览器标签页绑定,关闭标签页/浏览器后数据就会自动清除,因此无法实现跨会话的登录态保留。
你当前的配置已经包含了 offline_access 权限,且 IdentityServer 令牌有效期设置为 30 天,只需要替换默认的存储实现就能实现需求。
方案:自定义存储实现 Cookie 持久化
因为 Blazor WASM 运行在浏览器沙箱中,无法直接操作 Cookie,需要通过 JS Interop 完成读写,步骤如下:
- 实现自定义
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); } }
- 注册自定义存储
修改你的启动配置,替换默认的用户存储:
builder.Services.AddOidcAuthentication(options => { builder.Configuration.Bind("Local", options.ProviderOptions); options.UserOptions.RoleClaim = "RoleName"; }) // 注入自定义Cookie存储 .AddUserStore<CookieUserStore>();
- 添加 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_accessscope 会自动获取刷新令牌,当 access_token 过期时,OIDC 组件会自动用刷新令牌向 IdentityServer 申请新的令牌,无需用户重新登录,完全匹配你30天有效期的需求。 - 如果你的 Blazor WASM 是 ASP.NET Core 托管模式部署,更推荐将令牌存储在后端的 HttpOnly Cookie 中,由后端代理转发 API 请求时携带令牌,彻底避免客户端令牌泄露风险。
内容的提问来源于stack exchange,提问作者Luís Antunes
相关产品推荐
相关产品推荐

