You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:13:12