在 Asp.Net Core 中向依赖注入的 HttpClient 添加 cookie

nig*_*awk 5 c# asp.net-core

如何添加 cookie 以HttpClient用于注入服务(示例)?我创建了一些服务ApiService,并且该服务已HttpClientCatalogService教程中一样注入。问题是,为了与外部 API 通信,我的服务必须有一个令牌,该令牌之前由另一个名为usingHttpClient的 API 接收。因此,当在前端 Web 应用程序中完成登录时:IdentityServiceLoginService

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");
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是,当使用 调用 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()
    });
Run Code Online (Sandbox Code Playgroud)

Nko*_*osi 4

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

var container = new CookieContainer();
services.AddSingleton(container);
Run Code Online (Sandbox Code Playgroud)

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

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
});
Run Code Online (Sandbox Code Playgroud)

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

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