C# 如何使用来自IHttpClientFactory的HttpClient向请求添加cookie

C# 如何使用来自IHttpClientFactory的HttpClient向请求添加cookie,c#,asp.net-core,dotnet-httpclient,httpclientfactory,C#,Asp.net Core,Dotnet Httpclient,Httpclientfactory,背景 我正在开发一个ASP.NET核心Web API,我们在API中调用第三方API。此第三方API要求每个请求都包含一个带有访问令牌的cookie。我们的API从一个声明(来自与请求相关联的用户的ClaimsPrincipal)中获取这个令牌 详细信息 显示了如何在请求上设置cookie,但该示例要求手动构造HttpClient(以便能够将HttpClientHandler与CookieContainer一起注入)。由于不希望手动实例化HttpClient,我宁愿通过DI注入HttpClien

背景
我正在开发一个ASP.NET核心Web API,我们在API中调用第三方API。此第三方API要求每个请求都包含一个带有访问令牌的cookie。我们的API从一个声明(来自与请求相关联的用户的
ClaimsPrincipal
)中获取这个令牌

详细信息
显示了如何在请求上设置cookie,但该示例要求手动构造
HttpClient
(以便能够将
HttpClientHandler
CookieContainer
一起注入)。由于不希望手动实例化
HttpClient
,我宁愿通过DI注入
HttpClient
,这说明了(usin
IHttpClientFactory

在我的服务中,我可以访问一个注入的
HttpClient
实例(
\u HttpClient
),最简单的功能如下所示:

public async Task<string> GetStatusAsync(ClaimsPrincipal user)
{
    // TODO: Add cookie with access token (from user's claims) before making request
    return await _httpClient.GetStringAsync(Endpoints.Status);
}
公共异步任务GetStatusAsync(ClaimsPrincipal用户)
{
//TODO:在发出请求之前添加带有访问令牌(来自用户声明)的cookie
返回wait_httpClient.GetStringAsync(Endpoints.Status);
}
询问如何在使用IHttpClientFactory时包含授权cookie,答案为。现在谈谈我的问题:

据我所见,您在应用程序启动时的服务配置期间设置了报头传播中间件(包括所有报头、cookie等)。但是,在我们的API中,在实际向第三方API发出请求之前,我没有身份验证cookie的值

问题

在发出实际请求之前,如何向使用
IHttpClientFactory
注入我的服务的
HttpClient
实例上的请求添加cookie?

您可以在AddHeaderPropagation配置函数中放置一个静态函数:

services.AddHeaderPropagation(options =>
    {
        options.Headers.Add(MyCookie());
    });
在MyOkie函数中, 获取当前上下文并从中提取所有需要的数据

如果您需要当前流或当前控制器中的某些内容,可以添加它
在httpSession内部,并将其放在MyOkie函数中。

解决方案确实可以使用。我只需要把所有的部件正确地组装起来

头传播在
ConfigureServices
中配置(在
Startup.cs
中)。由于我想使用来自当前用户声明的数据,所以技巧在于,在添加cookie头时,使用函数中的重载,使您能够访问当前上下文:

services.AddHeaderPropagation(options =>
{
    options.Headers.Add("Cookie", context =>
    {
        var accessToken = context.HttpContext.User.Claims.FirstOrDefault(c => c.Type == "access-token")?.Value;
        return accessToken != null ? new StringValues($"token={accessToken}") : new StringValues();
    });
});
除此之外,由于我使用的是,我还必须配置特定服务转发cookie头(在
Startup.cs中
ConfigureServices
的同一位置):

services.AddHttpClient(httpClient=>
{
httpClient.BaseAddress=新Uri(“https://httpbin.org/");
}).AddHeaderPropagation(选项=>
{
选项。标题。添加(“Cookie”);
});
最后,给我带来了一些麻烦的事情:因为我使用的是来自当前用户声明的数据,所以必须在添加身份验证中间件之后注册报头传播中间件(
app.UseHeaderPropagation();
inside
Configure
in
Startup.cs
)(
app.UseAuthentication();
)。如果没有,则尚未设置声明


最后一点提示:在处理这个问题时,我会给大家介绍一下。那里的请求检查端点非常有用,可以查看您在请求中实际传递了哪些数据。

您可以使用
ConfigurePrimaryHttpMessageHandler()
方法在设置HttpClientFactory时配置主处理程序,该方法应允许您使用
HttpClientHandler
使用
Cookie
类配置Cookie。感谢您的响应。解决方案是使用头传播,但使用当前上下文(通过
标题之一提供。添加
重载),如下所示:
services.AddHttpClient<IApiService, ApiService>(httpClient =>
{
    httpClient.BaseAddress = new Uri("https://httpbin.org/");
}).AddHeaderPropagation(options =>
{
    options.Headers.Add("Cookie");
});