如何修复无法发送 GET 请求 - 403 错误

How to fix Unable to send GET request - 403 error

我是 C# 世界的新手,一直想不出如何解决这个错误。我正在尝试使用平台 API 密钥发出简单的获取请求。我已经在同一台笔记本电脑上的 Google App Script 中构建了 API 连接,它工作正常,但是当尝试在 C# 中构建相同的 API 时,它返回:

{StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Date: Sun, 13 Mar 2022 02:41:29 GMT
  Transfer-Encoding: chunked
  Connection: close
  CF-Chl-Bypass: 1
  Permissions-Policy: accelerometer=(),autoplay=(),camera=(),clipboard-read=(),clipboard-write=(),fullscreen=(),geolocation=(),gyroscope=(),hid=(),interest-cohort=(),magnetometer=(),microphone=(),payment=(),publickey-credentials-get=(),screen-wake-lock=(),serial=(),sync-xhr=(),usb=()
  Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  X-Frame-Options: SAMEORIGIN
  Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
  Strict-Transport-Security: max-age=2592000
  Server: cloudflare
  CF-RAY: 6eb1692f8bd776c3-LHR
  Content-Type: text/html; charset=utf-8
  Expires: Thu, 01 Jan 1970 00:00:01 GMT
}}

API 文档说:

"To authenticate against the API, include your API key in the 'Authorization' header, prefixed with 'Key ', in every request. Example: 'Authorization: Key yourapikey'"

因此,我尝试将其添加到
a) HttpClient 通过 HttpClient.DefaultRequestHeaders.Authorization
b) HttpClient 通过 HttpClient.DefaultHeaders.Add
c) 通过 HttpRequestMessage.Headers.Add
的 HttpRequestMessage 在每个实例中,请求 URI 和 headers 看起来都不错,但仍然返回 403.
我当前的结构是:

// services
builder.Services.AddHttpClient("myplatform", c =>
{
    c.BaseAddress = new Uri("https://seller-api.myplatform.com/v2/");
    c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
});

// controller
// constructor uses IHttpClientFactory
this._httpClient = clientFactory.CreateClient("myplatform");

// service
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Key", platformKey);

string endPoint = "offers" + CreateQueryString(pageNumber, pageSize);
// example endPoint: offers?page_number=1&page_size=100

var requestMsg = new HttpRequestMessage()
{
     Method = HttpMethod.Get,
     RequestUri = new Uri(httpClient.BaseAddress + endPoint)
};

try
{    
     var result = await httpClient.SendAsync(requestMsg);
}
catch (Exception ex)
{
                    
}

同样,当通过 GoogleAppScript 调用时,调用内容有效。我在 C# 中做错了什么,我该如何纠正?

不确定这是否是所需的全部信息 - 否则请告诉我!需要注意的重要一点是,目标框架是 .NET 6.0.

编辑

正如关于重复客户的评论所建议的,我已经删除了客户工厂。我现在正在控制器构造函数中创建一个新的 HttpClient,并将此客户端传递给我的服务以执行 GET 请求。

this._httpClient = new HttpClient();

同样,客户端和请求消息在请求时看起来格式正确,但仍然返回 403 error。我的 VS22 客户端或 Web 客户端等有问题吗?

此外,我通过 Google AppScript 成功进行的调用正在使用 UrlFetchApp。不确定 C# 方面的问题是什么..

EDIT2

添加当前 GAS 代码以供参考:

var url = 'https://seller-api.platform.com/v2';
var end_point = '/offers?';
var header = {
    'Authorization': api_key
  }
var params = {
    'method': 'GET',
    'headers': header
  }

// call API
var page_query = 'page_number=' + page + '&page_size=' + maxItemsPerPage;
var full_url = url + end_point + page_query;

var response = UrlFetchApp.fetch(full_url, params);

HTTP 403 Forbidden response 状态码表示服务器理解请求但拒绝授权。

使用HttpClient时添加请求headers有两种方式:

  • 为所有使用 HttpClient.DefaultRequestHeaders 的请求添加 headers。
        HttpClient = new HttpClient();
        HttpClient.DefaultRequestHeaders.Add("Key", platformKey);
        var response = await HttpClient.GetAsync(GetRandomNumberUrl);
        response.EnsureSuccessStatusCode();
        await response.Content.ReadAsStringAsync();
  • 使用 HttpRequestMessage.Headers.
  • 每个请求添加 headers
        HttpClient = new HttpClient();
        using (var request = new HttpRequestMessage(HttpMethod.Get, randomNumberUrl))
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", platformKey);
            var response = await HttpClient.SendAsync(request);

            response.EnsureSuccessStatusCode();

            await response.Content.ReadAsStringAsync();
        }

你的问题在这一行:

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Key", platformKey);

你的 _httpClient 和 Authorization httpClient 不是同一个实例。

试试这个方法:

                HttpClient HttpClient = new HttpClient();
                string url = "https://seller-api.platform.com/v2";
                string end_point = "/offers?";
                string api_key = "key here";
                string page_query = "page_number=" + 10 + "&page_size=" + 20;
                string full_url = url + end_point + page_query;

                using (var request = new HttpRequestMessage(HttpMethod.Get, url))
                {
                    request.Headers.Add("Authorization", api_key);
                    var response = await HttpClient.SendAsync(request);

                    response.EnsureSuccessStatusCode();

                    var m = await response.Content.ReadAsStringAsync();
                }

方案二: 尝试调用它 like a browser :

                HttpClient httpClient = new HttpClient();
                string url = "https://gatewayt.whatever.com/chkt/request/request.php";
                string end_point = "/offers?";
               string  api_key = "key here";
                string page_query = "page_number=" + 10 + "&page_size=" + 20;
                string full_url = url + end_point + page_query;

                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Key", api_key);

                var response = await httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();
                await response.Content.ReadAsStringAsync();

来源:Request like browser Link1 Link2 Link3