【发布时间】:2020-01-11 00:27:21
【问题描述】:
如何将 cookie 添加到注入服务 (example) 中使用的 HttpClient?我创建了一些服务ApiService,并且该服务注入了HttpClient,就像教程中的CatalogService 一样。问题是,为了与外部 API 通信,我的服务和它的 HttpClient 必须有一个令牌,该令牌以前由另一个名为 IdentityService 的 API 使用 LoginService 接收。因此,当在前端 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);
}
}
结果是,当使用HttpClient 调用 API 时,没有“令牌”cookie...知道如何更改它,以便ApiService 的HttpClient 不会丢失其接收到的 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()
});
【问题讨论】:
-
删除 HttpClient 并在您的构造函数中添加 «IHttpClientFactory factory»。然后调用«_client = clientFactory.CreateClient("apiServiceClient")»。我认为这应该可以获取保存 cookie 的正确实例
标签: c# asp.net-core