将 cookie 添加到 Asp.Net Core 中注入依赖关系的 HttpClient



如何将 cookie 添加到注入服务中使用的HttpClient(示例(?我已经创建了一些服务ApiService并且该服务HttpClient就像教程中的CatalogService一样注入。问题是,为了与外部 API 通信,我的服务和它的HttpClient必须有一个令牌,该令牌之前由另一个使用LoginService的名为IdentityService的 API 接收。因此,当登录在前面的 Web 应用程序中完成时:

if (!string.IsNullOrEmpty(user.Token)) {
ClaimsPrincipal principal = ValidateToken(user.Token);
if (principal != null) {
AuthenticationProperties p = new AuthenticationProperties();
p.ExpiresUtc = DateTime.UtcNow.AddDays(7);
p.IsPersistent = Persistant;
p.RedirectUri = Request.Query.ContainsKey("ReturnUrl") ? Request.Query["ReturnUrl"].ToString() : "";
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, p);
// those cookies are lost when ApiController is called - new instance of http client replaces this one
var apiService = HttpContext.RequestServices.GetService(typeof(IApiService));
var s = apiService as ApiService;
s.SetClientCookies("token", user.Token);
return new RedirectToPageResult("../Index");
}
}
return BadRequest("Invalid token");

SetClientCookies目前看起来像这样,但它不起作用,因为 ApiService 构造函数获得了 HttpClient 的新实例:

public class ApiService: IApiService {
public static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
private HttpClient _client;
static string BaseUrl = "https://localhost:44365/api";
public ApiService(HttpClient client) {
_client = client;
}
public async Task < List < DbTest >> GetAccounts() {
var httpResponse = await _client.GetAsync(BaseUrl + "/account");
if (!httpResponse.IsSuccessStatusCode) {
throw new Exception("Cannot retrieve login");
}
var content = await httpResponse.Content.ReadAsStringAsync();
var accounts = JsonConvert.DeserializeObject < List < DbTest >> (content);
return accounts;
}
public void SetClientCookies(string key, string value) {
_client.DefaultRequestHeaders.Add("Cookie", key + "=" + value);
}
}

结果是,当 API 被调用时HttpClient,没有"令牌"cookie...知道如何更改它以使ApiServiceHttpClient不会丢失登录时收到的cookie吗?

相关Startup.cs代码如下:

services.AddHttpClient<ILoginService, LoginService>("identityServiceClient");
services.AddHttpClient<IApiService, ApiService>("apiServiceClient")
.ConfigureHttpClient(client => {
client.Timeout = TimeSpan.FromSeconds(30);
}).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() {
CookieContainer = new CookieContainer()
});

一种可能性是将 cookie 容器添加到服务集合中

var container = new CookieContainer();
services.AddSingleton(container);

并在注册客户端时使用该实例

services.AddHttpClient<IApiService, ApiService>(client => {
client.Timeout = TimeSpan.FromSeconds(30);
client.BaseAddress = new Uri("https://localhost:44365/api").
}).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() {
CookieContainer = container,
UseCookies = true
});

现在,可以根据需要解析和操作容器。

var container = HttpContext.RequestServices.GetService<CookieContainer>();
container.Add(BaseUrl, new Cookie("token", user.Token));

相关内容

  • 没有找到相关文章