FlUrl 4.0:如何结合WithOAuthBearerToken与依赖容器实现认证请求
FlUrl 4.0 适配原单例客户端方案的迁移指导
针对你在FlUrl 3.X中使用双单例客户端(无授权登录用、授权后请求用)的场景,结合FlUrl 4.0的设计变更,可通过命名客户端 + IFlurlClientCache管理的方式实现适配,具体步骤如下:
1. 注册命名客户端
在依赖注入容器中,通过AddFlurlClients注册两个命名客户端,分别对应原_noAuthClient和_authClient,同时配置全局默认规则:
builder.Services.AddFlurlClients(config => { // 全局默认配置(如基础地址、超时、日志等) config.WithDefaults(builder => { builder.BaseUrl("https://your-api-domain.com"); builder.WithTimeout(TimeSpan.FromSeconds(30)); // 可添加全局拦截器、序列化配置等 }); // 注册无授权客户端(用于登录请求) config.Add("NoAuth", builder => { // 继承全局配置,无需额外授权相关配置 builder.BaseUrl("https://your-api-domain.com"); }); // 注册授权客户端(用于登录后的所有请求) config.Add("Auth", builder => { builder.BaseUrl("https://your-api-domain.com"); // 暂不配置授权头,后续动态注入 }); });
2. 使用无授权客户端调用登录接口
在登录服务中注入IFlurlClientCache,通过客户端名称获取实例发起登录请求,获取JWT Token:
public class AuthService { private readonly IFlurlClientCache _clientCache; public AuthService(IFlurlClientCache clientCache) { _clientCache = clientCache; } public async Task<string> LoginAsync(string username, string password) { var loginResponse = await _clientCache.Get("NoAuth") .Request("/api/auth/login") .PostJsonAsync(new { Username = username, Password = password }) .ReceiveJson<LoginResponse>(); return loginResponse.JwtToken; } }
3. 为授权客户端动态注入JWT Token
针对授权客户端的Token注入,推荐使用全局拦截器实现自动添加,避免重复代码:
步骤3.1 实现Token提供服务
先定义一个用于获取当前有效Token的服务(比如从HttpContext或Token存储中获取):
public interface IAuthTokenProvider { Task<string> GetCurrentTokenAsync(); } public class AuthTokenProvider : IAuthTokenProvider { private readonly IHttpContextAccessor _httpContextAccessor; public AuthTokenProvider(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public Task<string> GetCurrentTokenAsync() { // 示例:从HttpContext的Claims或Session中获取Token var token = _httpContextAccessor.HttpContext?.User.FindFirst("JwtToken")?.Value; return Task.FromResult(token); } }
步骤3.2 注册拦截器自动添加授权头
在Program.cs中配置FlUrl全局拦截器,针对Auth命名客户端自动注入Token:
// 先注册Token提供服务 builder.Services.AddScoped<IAuthTokenProvider, AuthTokenProvider>(); builder.Services.AddHttpContextAccessor(); // 配置FlUrl全局拦截器 FlurlHttp.Configure(settings => { settings.BeforeCallAsync = async call => { // 仅对Auth客户端添加授权头 if (call.Client.Name == "Auth") { var tokenProvider = call.HttpContext.RequestServices.GetRequiredService<IAuthTokenProvider>(); var token = await tokenProvider.GetCurrentTokenAsync(); if (!string.IsNullOrEmpty(token)) { call.Request.WithOAuthBearerToken(token); } } }; });
4. 使用授权客户端发起业务请求
在业务服务中注入IFlurlClientCache,获取Auth客户端即可发起带授权的请求,无需手动添加Token:
public class DataService { private readonly IFlurlClientCache _clientCache; public DataService(IFlurlClientCache clientCache) { _clientCache = clientCache; } public async Task<MyDataDto> GetDataAsync(int id) { return await _clientCache.Get("Auth") .Request("/api/data/{id}", id) .GetJsonAsync<MyDataDto>(); } }
内容的提问来源于stack exchange,提问作者Karel Kral
相关产品推荐
相关产品推荐

