Blazor跳转外部登录页返回应用后如何获取访问令牌?
Blazor 混合架构下令牌获取服务实现
核心实现逻辑
Blazor Server 模式下,组件无法直接稳定访问HttpContext的本质原因是两者生命周期不同步,要实现可跨页面、组件复用的作用域令牌获取服务,不需要手动解密认证Cookie,直接基于内置的令牌查询能力封装即可,步骤如下:
- 第一步:注册必须的基础依赖
在Program.cs的服务注册段,先补全HttpContext的访问能力(如果之前未配置的话):builder.Services.AddHttpContextAccessor(); - 第二步:定义令牌服务接口
单独建立服务文件,定义需要的令牌查询方法:public interface ITokenProvider { /// <summary>获取OpenIdConnect存储的访问令牌</summary> Task<string?> GetAccessTokenAsync(); /// <summary>获取OpenIdConnect存储的身份令牌</summary> Task<string?> GetIdTokenAsync(); /// <summary>获取OpenIdConnect存储的刷新令牌</summary> Task<string?> GetRefreshTokenAsync(); } - 第三步:实现服务逻辑
利用内置的AuthenticationHttpContextExtensions.GetTokenAsync方法直接从当前请求的认证Cookie中读取已保存的令牌,不需要手动处理Cookie解密:public class BlazorTokenProvider : ITokenProvider { private readonly IHttpContextAccessor _httpContextAccessor; public BlazorTokenProvider(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public async Task<string?> GetAccessTokenAsync() { var httpContext = _httpContextAccessor.HttpContext; return httpContext == null ? null : await httpContext.GetTokenAsync("access_token"); } public async Task<string?> GetIdTokenAsync() { var httpContext = _httpContextAccessor.HttpContext; return httpContext == null ? null : await httpContext.GetTokenAsync("id_token"); } public async Task<string?> GetRefreshTokenAsync() { var httpContext = _httpContextAccessor.HttpContext; return httpContext == null ? null : await httpContext.GetTokenAsync("refresh_token"); } } - 第四步:注册为作用域服务
服务生命周期要和Blazor电路、HTTP请求保持一致,注册为Scoped即可:builder.Services.AddScoped<ITokenProvider, BlazorTokenProvider>(); - 使用方式
不管是LoginCallback.razor这类回调组件,还是其他需要取令牌的业务组件,直接通过依赖注入调用即可,不需要额外处理:
只要你在OpenIdConnect配置中启用了SaveTokens=true,以上方法读取的就是存储在认证Cookie中的对应令牌值,不需要额外解析Cookie。@inject ITokenProvider TokenProvider @code { protected override async Task OnInitializedAsync() { // 在回调页直接读取令牌执行后续逻辑 var accessToken = await TokenProvider.GetAccessTokenAsync(); var refreshToken = await TokenProvider.GetRefreshTokenAsync(); // 此处完成登录后的自定义业务逻辑 } }
剩余需求的实现说明
- 解决Dashboard跳转前短暂加载的闪屏问题
闪屏的本质是授权判断逻辑跑在了组件初始化流程之后,需要把授权判断前置到路由匹配阶段:在App.razor中给Router组件替换为<AuthorizeRouteView>,未授权用户会在路由匹配完成后直接触发跳转,不会进入Dashboard组件的初始化、渲染流程,从根源上消除闪屏。 - 调整_Imports.razor的全局授权规则
直接在_Imports.razor的全局属性区添加全局授权特性:
所有未单独标注权限特性的组件默认要求授权;再给Home、Login对应的razor页面单独加上匿名访问特性:@attribute [Authorize]
即可完成公开页面的放行配置。@attribute [AllowAnonymous]
内容的提问来源于stack exchange,提问作者Ivan-Mark Debono
相关产品推荐
相关产品推荐

