首页 > 解决方案 > 难以从 API 接收 HTTP 响应 - 错误请求错误

问题描述

我正在尝试将用户名/密码从应用程序传递到 API 以接收令牌授权密钥。当我尝试这样做时,我收到 400 Bad Request 错误,我不知道为什么。以下是有问题的方法:

public User UserAuthentication(string username, string password)
{
    string endpoint = baseURL + "/TOKEN";

    // Could be POST maybe
    string method = "POST";

    Credential jsonObj = new Credential
                         {
                            grant_type = "password",
                            username = username,
                            password = password
                         };

    string jsonStr = JsonConvert.SerializeObject(jsonObj);

    WebClient wc = new WebClient();

    //x - www - form - urlencoded
    wc.Headers[HttpRequestHeader.ContentType] = "application/x - www - form - urlencoded";
    wc.Headers.Add("Access-Control-Allow-Headers", "content-type");
    wc.Headers.Add("Access-Control-Allow-Origin", "*");
    wc.Headers[HttpRequestHeader.Authorization] = "Bearer <token>";
    wc.Headers.Add("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, OPTIONS");

    string header = wc.Headers.ToString();

    try
    {
        string response = wc.UploadString(endpoint, method, jsonStr);
        return JsonConvert.DeserializeObject<User>(response);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

我已经在这个方法中改变了几乎所有的东西来寻找修复。

我做了什么:

标题:

{Content-Type: application/x - www - form - urlencoded
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Origin: *
Authorization: Bearer <token>
Access-Control-Allow-Methods: POST, PUT, GET, DELETE, OPTIONS}

身体:

{"grant_type":"password",
"username":"test@gmail.com",
"password":"password123"}

I obviously have something wrong in my request, I've just run out of ideas to try. I'm not entirely sure if UploadString() is the correct method to be using in this situation, but I couldn't find another method in the WebClient class that would be better. Any help to try and push me in the right direction would be very much appreciated.

标签: c#jsonwpfserializationhttp-headers

解决方案


So what I think you are trying to do is a form-urlencoded post to a "token" endpoint with a username/password grant. These are typically done like so:

using (var request = new HttpRequestMessage(HttpMethod.Post, new Uri("https://example.com/token"))
{
    Content = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        { "grant_type", "password" },
        { "username", "username@site.com" },
        { "password", "password12345" }
    })
})
{
    using (var resp = await _client.SendAsync(request))
    {
        resp.EnsureSuccessStatusCode();
        //await resp.Content.ReadAsAsync<BearerToken>();
        // for testing purposes, try this:
        var returnData = await resp.Content.ReadAsStringAsync();
        Console.WriteLine(returnData);
    }
}

You should define this outside all scopes where you need to do Http requests:

private static readonly HttpClient _client = new HttpClient();

So, first off, try to stick with HttpClient. Other patterns such as WebClient are considered legacy.

Next, CORS headers are typically returned from the server when an OPTIONS call is sent to the server. You aren't doing that here, and you should never have to worry about that kind of stuff inside a C# program running from your computer. So you can drop the access-control header stuff.

Form-urlencoded data is not JSON data. It's a different way to format data. If you want to send JSON data, you should use the content-type application/json

Finally, you are trying to add an Authorization header. But that doesn't make much sense as you are trying to authenticate yourself to become authorized. If you send the right username/password, you will receive a bearer token that you can use in an Authorization header for future requests to said service.

Oh and I forgot to add: Whenever you see an error in the [400,499] range (in this case "400 - bad request") it means that you sent something wrong and the server doesn't understand what you are trying to do. For example: a 401 means you sent invalid or missing authorization information. A 400 means your data was probably malformed.

But I like your question... I can see what you were doing and you tried all kinds of different things.

Download a program called Fiddler if you want to see how HTTP works. It's a great tool to debug your HTTP calls.


推荐阅读