How to add a cookie to a request using HttpClient from IHttpClientFactory(如何使用HttpClient从IHttpClientFactory向请求添加Cookie)
问题描述
背景
我正在开发一个ASP.NET Core Web API,其中我们在API中调用第三方API。此第三方API要求每个请求都包含带有访问令牌的Cookie。我们的API从声明(从与请求相关联的用户的ClaimsPrincipal
)获取该令牌。
详细信息
This answer显示如何在请求上设置cookie,但该示例需要手动构造HttpClient
(以便能够使用CookieContainer
注入HttpClientHandler
)。由于不希望手动实例化HttpClient
,我宁愿通过this example说明的DI注入HttpClient
。
在我的服务中,我可以访问一个注入的HttpClient
实例(_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);
}
This GitHub issue询问使用IHttpClientFactory时如何包含授权cookie,答案是use the header propagation middleware。现在来谈谈我的问题:
在我看来,您在应用程序启动时的服务配置期间设置了头传播中间件(具有所有头和Cookie等)。但是,在我们的API中,在实际向第三方API发出请求之前,我没有身份验证Cookie的值。问题
如何在发出实际请求之前使用IHttpClientFactory
将Cookie添加到HttpClient
实例上的请求?
推荐答案
解决方案确实是使用header propagation。我只需要把所有的东西都正确地组合在一起。
头部传播配置在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();
});
});
除此之外,由于我使用Typed Service,我还必须配置该特定服务应该转发Cookie标头(在Startup.cs
中ConfigureServices
中相同位置):
services.AddHttpClient<IApiService, ApiService>(httpClient =>
{
httpClient.BaseAddress = new Uri("https://httpbin.org/");
}).AddHeaderPropagation(options =>
{
options.Headers.Add("Cookie");
});
最后,有一件事给我带来了一些麻烦:因为我使用的是来自当前用户的数据,所以必须在添加身份验证中间件(app.UseAuthentication();
)之后注册头传播中间件(app.UseHeaderPropagation();
内部Startup.cs
)。如果不是,则尚未设置声明。
作为最后一个提示:我在https://httpbin.org/中工作时很棒。那里的请求检查端点对于查看您的请求中实际传递了哪些数据非常有用。
这篇关于如何使用HttpClient从IHttpClientFactory向请求添加Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何使用HttpClient从IHttpClientFactory向请求添加Coo


- 在 C# 中异步处理项目队列 2022-01-01
- 在 LINQ to SQL 中使用 contains() 2022-01-01
- 使用 rss + c# 2022-01-01
- 是否可以在 .Net 3.5 中进行通用控件? 2022-01-01
- CanBeNull和ReSharper-将其用于异步任务? 2022-01-01
- Windows 喜欢在 LINUX 中使用 MONO 进行服务开发? 2022-01-01
- Azure Active Directory 与 MVC,客户端和资源标识同一 2022-01-01
- 带问号的 nvarchar 列结果 2022-01-01
- C# 通过连接字符串检索正确的 DbConnection 对象 2022-01-01
- 为什么 C# 中的堆栈大小正好是 1 MB? 2022-01-01