如何在Blazor WASM的Program.cs中访问会话存储并获取id_token?
核心问题说明
你在AddHttpClient委托中直接赋值请求头的方案不可行,原因有两点:
- 该委托仅在HttpClient首次实例化时执行一次,无法动态更新即将过期的
id_token - 服务注册阶段用户尚未完成登录流程,会话存储中不存在
id_token,不可能在启动阶段拿到该值
可行解决方案
通过自定义DelegatingHandler拦截所有发往网关的请求,在请求发送前动态获取当前用户的id_token注入请求头,具体实现步骤如下:
- 第一步:开启令牌持久化配置
首先在Program.cs的OIDC身份认证配置中开启令牌保存,确保id_token会被存储到本地:
builder.Services.AddOidcAuthentication(options => { // 保留你原有Google身份提供方的配置 options.ProviderOptions.SaveTokens = true; // 必须开启该配置,才会持久化id_token、access_token等令牌 });
- 第二步:实现自定义请求拦截Handler
创建GoogleIdTokenHandler类继承DelegatingHandler,实现每次请求前动态获取id_token的逻辑:
using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebAssembly.Authentication; public class GoogleIdTokenHandler : DelegatingHandler { private readonly ITokenService _tokenService; public GoogleIdTokenHandler(ITokenService tokenService) { _tokenService = tokenService; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var tokenResult = await _tokenService.GetTokenAsync(); if (!string.IsNullOrEmpty(tokenResult.IdToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.IdToken); } // 可在此处扩展未登录跳转、令牌过期刷新等逻辑 return await base.SendAsync(request, cancellationToken); } }
- 第三步:注册服务并绑定HttpClient
在Program.cs中注册自定义Handler,并且将其绑定到你的网关HttpClient上:
// 注册自定义请求拦截Handler builder.Services.AddScoped<GoogleIdTokenHandler>(); // 配置网关HttpClient,添加请求拦截逻辑 builder.Services.AddHttpClient("GatewayApi", client => { client.BaseAddress = new Uri(builder.Configuration["GatewayServiceConfiguration:BaseUrl"]); }) .AddHttpMessageHandler<GoogleIdTokenHandler>();
后续使用说明
后续你通过IHttpClientFactory获取名为GatewayApi的HttpClient发起请求时,会自动触发拦截逻辑,将当前用户的id_token注入到Authorization请求头中,无需在业务代码中手动处理令牌。
内容的提问来源于stack exchange,提问作者SachinK
相关产品推荐
相关产品推荐

