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
,这说明了(usinIHttpClientFactory
)
在我的服务中,我可以访问一个注入的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();
insideConfigure
inStartup.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");
});