可以通过在程序中使用持久化的本地存储来保存用户的身份验证令牌,以便在下一次启动时自动使用。以下是示例代码:
在 Blazor WASM 项目中,在 Program.cs 文件的 Main 方法中添加以下代码:
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("app");
// 添加身份验证服务
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped();
builder.Services.AddScoped();
// 添加请求拦截器
builder.Services.AddTransient();
builder.Services.AddHttpClient("authorizedClient", client =>
{
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
})
.AddHttpMessageHandler();
// 创建 WebAssemblyHost
var host = builder.Build();
// 解析 IAuthService
var authService = host.Services.GetRequiredService();
// 尝试登录
var result = await authService.Login(new LoginRequest { Username="username", Password="password" });
if (!result.Success)
{
// 登录失败
}
else
{
// 保存 token
await host.WriteUserTokenAsync(result.Token);
}
await host.RunAsync();
JwtAuthenticationStateProvider.cs:
public class JwtAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly ILocalStorageService localStorage;
public JwtAuthenticationStateProvider(ILocalStorageService localStorage)
{
this.localStorage = localStorage;
}
public override async Task GetAuthenticationStateAsync()
{
var token = await localStorage.GetItemAsync("token");
if (string.IsNullOrEmpty(token))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
var claims = ParseClaimsFromJwt(token);
var identity = new ClaimsIdentity(claims, "BearerToken");
var user = new ClaimsPrincipal(identity);
return new AuthenticationState(user);
}
public async Task SetAuthenticationStateAsync(string token)
{
await localStorage.SetItemAsync("token", token);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
public async Task ClearAuthenticationStateAsync()
{
await localStorage.RemoveItemAsync("token");
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
private static IEnumerable ParseClaimsFromJwt(string jwt)
{
var claims = new List();
var payload = jwt.Split('.')[1];
var jsonBytes = ParseBase64WithoutPadding(payload);
var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes);
keyValuePairs.TryGetValue(ClaimTypes.Role, out object roles);
if (roles != null)
{
if (roles.ToString