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.
中的重定向
我将 HttpClientHandler
和 AllowAutoRedirect = 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
我想通过 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.
中的重定向我将 HttpClientHandler
和 AllowAutoRedirect = 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