C# HttpClient 授权 header 在发送到服务器后删除

C# HttpClient authorization header removed after send to server

我想通过 HttpClient 从我自己的 API 在 c# 中向外部 API 发送请求。 我正在使用 dot net 5 和基本身份验证。 这是我的代码:

var client = new HttpClient 
{
    BaseAddress = new Uri(baseUrl)
};

HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, "apiUrl");

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var param = JsonConvert.SerializeObject(new
{
   param1="",
   param2=""
});

requestMessage.Content = new StringContent(param, Encoding.UTF8, "application/json");
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic",
     Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pass}")));

HttpResponseMessage response = await client.SendAsync(requestMessage);

平时我都是这样发送http请求的。 但现在我遇到了一些问题。

在行 HttpResponseMessage response = await client.SendAsync(requestMessage); 授权 header 从我的请求中删除 header 之后,我得到了 UnAuthorized http 错误。

我知道发生重定向时,出于安全原因删除了授权 header。另外我不确定外部 API.

中的重定向

我将 HttpClientHandlerAllowAutoRedirect = false 添加到我的 HttpClient

var handler = new HttpClientHandler()
{
    AllowAutoRedirect = false,
};
var client = new HttpClient (handler)
{
    BaseAddress = new Uri(baseUrl)
};

现在我收到重定向错误 301(永久移动)。

我决定在 Postman 中测试代码。默认情况下,当我在 Postman 中调用 API 时,我得到了不允许的 http 错误 405 错误详细信息如下:

{ "detail": "Method "GET" not allowed."}

外部 API 方法是 PUT。但在这里我得到 GET 错误。 我在邮递员中尝试了很多选项,最后我在邮递员中找到了选项:

当我打开它时,外部 API 工作正常。 我也用 Insomnia 测试它,它工作正常。

它是否与我的代码或 dot net 5 或我的代码中的其他内容有关,或者是否与外部有关 API?

如果与我的代码有关,我该如何解决错误?

如果错误与外部相关 API,为什么 Postman 和 Insomnia 响应正常?

外部 API 有特定域的核心策略,我从其他域发送请求。 我所知道的是在浏览器中应用了 CORS 策略。不在 Postman、Insomnia 或 C# 代码中。 CORS 呢?它与CORS有关吗?如果是,我该怎么办?

非常感谢您的回答。

更新

我在响应 header 中检测到 WWW-Authenticate: JWT realm="api"。 它到底是什么?我该怎么办?

由于您看到 WWW-Authenticate: JWT realm="api" header,外部 API 需要 JWT 令牌身份验证,而不是基本身份验证。我认为首先您可能需要检查外部 api 的文档。

您关于在重定向后删除授权 header 的说法是正确的。但请记住,此行为是 C# 中 HttpClient 设计的一部分。 Postman 和 Insomnia 可能有不同的机制在重定向引起的每个连续请求上发送授权 headers。您在 Postman 中启用的选项将使其使用您指定的原始 HTTP 方法 (PUT) 作为 HTTP 方法,以根据重定向消息发送进一步的请求(邮递员使用 GET 方法默认情况下根据重定向消息指示的请求。

您看到 301 表明需要重定向。您可以检查 response.Headers 中的 Location header 值以查看真实位置,并将具有授权 headers 的请求直接发送到该端点。如果我是你,我不会直接使用新位置,因为原始端点是 API 的作者给你的。相反,我会以编程方式将请求发送到原始端点,并将 301 代码上的请求重新发送到新的 Location(由于 Postman 的行为,使用 PUT 方法),直到获得结果。这个答案可以给你一些想法:https://whosebug.com/a/42566541/1539231

我找到问题了。这真的很荒谬。 当我使用像 www.abc.com/api/something 这样的 URL 时,请求出现 301 错误并且邮递员发送另一个像 www.abc.com/api/something/ 这样的请求。区别只是请求结束时的 / 。 我在邮递员中尝试了新的 URL 并且第一个请求没问题。 我还尝试了 URL 在我的 C# 代码中,再次确定。 但是我不明白为什么。

非常感谢亲爱的@pharaz-fadaei