HTTP API代码返回403禁止,但 Postman 的工作-困惑

ssgvzors  于 2023-10-18  发布在  Postman
关注(0)|答案(2)|浏览(308)

我正试图将来自transfernow.net的HTTP API集成到我的Windows窗体应用程序中,但我遇到了一个奇怪的砖墙...
我已经用我的密钥测试了postman中的API调用,它工作得很好,但是下面的C#返回了一个403禁止,你们中的任何一个天才程序员能指出我的代码中是否有什么缺陷会导致这个问题吗(我也联系了Transfernow,但预计他们不会很快响应)

static async Task<string> SendPostRequestAsync()
{
            System.Net.ServicePointManager.SecurityProtocol System.Net.SecurityProtocolType.Tls12;

            using (var httpClient = new HttpClient())
            {
                using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.transfernow.net/v1/transfers"))
                {
                    request.Headers.TryAddWithoutValidation("x-api-key", "xxxxxx"); //removed for security reasons but was the same as used in postman

                    request.Content = new StringContent("{\n        \"langCode\": \"en\",\n        \"toEmails\": [\"[email protected]\", \"[email protected]\"],\n        \"files\": [{\n          \"name\": \"file1.txt\",\n          \"size\": 14587\n        },{\n          \"name\": \"music.mp3\",\n          \"size\": 5496409\n        }],\n        \"message\": \"A brillant transfer content, thank you\",\n        \"subject\": \"Text and Music\",\n        \"validityStart\": \"2022-10-28T08:52:25.955Z\",\n        \"validityEnd\": \"2022-11-01T08:52:25.955Z\",\n        \"allowPreview\": true,\n        \"maxDownloads\": 7\n      }");
                    request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                    var response = await httpClient.SendAsync(request);
                    if (response.IsSuccessStatusCode)
                    {
                        // Return the response content as a string
                        return await response.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        // Handle an error response here
                        MessageBox.Show("Error: " + response.StatusCode, "API Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return null;
                    }
                }
            }
            
            
        }

如果你能帮忙的话,我将不胜感激。
我试过使用https://curl.olsh.me/转换transfernow文档中的curl代码,甚至使用postman来生成,但都没有帮助我通过这个问题。
Postman 按要求生成代码:

var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.transfernow.net/v1/transfers");
request.Headers.Add("x-api-key", "xxx");
var content = new StringContent("{\r\n        \"langCode\": \"en\",\r\n        \"toEmails\": [\"[email protected]\", \"[email protected]\"],\r\n        \"files\": [{\r\n          \"name\": \"P:\\\\events\\\\test\\\\export\\\\DRB_0221woodlands.jpg\",\r\n          \"size\": 2843846 \r\n        },{\r\n          \"name\": \"P:\\\\events\\\\test\\\\export\\\\DRB_0222woodlands.jpg\",\r\n          \"size\": 2843846 \r\n        }],\r\n        \"message\": \"A brillant transfer content, thank you\",\r\n        \"subject\": \"Text and Music\",\r\n        \"allowPreview\": true,\r\n        \"maxDownloads\": 7\r\n      }", null, "application/json");
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());

Postman 生成的HTTP代码:

POST /v1/transfers HTTP/1.1
Host: api.transfernow.net
Content-Type: application/json
x-api-key: xxxxxx
Content-Length: 517

{
        "langCode": "en",
        "toEmails": ["[email protected]", "[email protected]"],
        "files": [{
          "name": "P:\\events\\test\\export\\DRB_0221woodlands.jpg",
          "size": 2843846 
        },{
          "name": "P:\\events\\test\\export\\DRB_0222woodlands.jpg",
          "size": 2843846 
        }],
        "message": "A brillant transfer content, thank you",
        "subject": "Text and Music",
        "allowPreview": true,
        "maxDownloads": 7
      }
ffvjumwh

ffvjumwh1#

显然他们也想要一个user-agent头。如果文档中提到这一点就好了。我注册了一个试用版,只有通过设置一个用户代理才能让它工作。你可能不需要这个确切的值,但这是Github CoPilot为我写的:
request.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/999.0.9999.999 Safari/537.36");
我以前在其他API中遇到过这种情况。如果有疑问,设置某种用户代理,看看它是否有帮助。

toe95027

toe950272#

可能还需要Content-Length HTTP头。

string content = "{\n        \"langCode\": \"en\",\n        \"toEmails\": [\"[email protected]\", \"[email protected]\"],\n        \"files\": [{\n          \"name\": \"file1.txt\",\n          \"size\": 14587\n        },{\n          \"name\": \"music.mp3\",\n          \"size\": 5496409\n        }],\n        \"message\": \"A brillant transfer content, thank you\",\n        \"subject\": \"Text and Music\",\n        \"validityStart\": \"2022-10-28T08:52:25.955Z\",\n        \"validityEnd\": \"2022-11-01T08:52:25.955Z\",\n        \"allowPreview\": true,\n        \"maxDownloads\": 7\n      }";

HttpContent httpContent =
    new StringContent(
        content,
        Encoding.UTF8,
        // This way you don't need to set Content-Type in a separate statement.
        // Built-in const: "application/json"
        System.Net.Mime.MediaTypeNames.Application.Json
    );

// Set the Content-Length header as well.
httpContent.Headers.ContentLength = Encoding.UTF8.GetBytes(content).LongLength;

request.Content = httpContent;

顺便说一句,我建议使用HttpMethod.Post,而不是每次都用new HttpMethod("POST")创建一个新示例。

相关问题