Сложность получения HTTP-ответа от API - ошибка неверного запроса - PullRequest
1 голос
/ 07 августа 2020

Я пытаюсь передать имя пользователя / пароль из приложения в 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());
    }
}

Я напортачил, изменив почти все в этом методе в поисках исправления.

Что я сделал:

  • / TOKEN было / values ​​& / api / values ​​
  • Метод POST был GET - при этом я получил сообщение «Невозможно отправить тело содержимого с этим типом глагола». ошибка.
  • ContentType был изменен на «application / json»
  • Access-Control-Allow-Origin имел baseURL
  • Проверил формат заголовка и тела:

Заголовок:

{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"}

У меня явно что-то не так в моем запросе, у меня просто закончились идеи попробовать. Я не совсем уверен, что UploadString () - правильный метод для использования в этой ситуации, но я не смог найти другого метода в классе WebClient, который был бы лучше. Мы будем очень благодарны за любую помощь, чтобы попытаться сделать sh меня в правильном направлении.

1 Ответ

1 голос
/ 07 августа 2020

Итак, я думаю, что вы пытаетесь сделать сообщение с URL-адресом в форме для конечной точки «токена» с предоставлением имени пользователя и пароля. Обычно это делается так:

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);
    }
}

Вы должны определить это вне всех областей, в которых вам нужно выполнять запросы Http:

private static readonly HttpClient _client = new HttpClient();

Итак, во-первых, попробуйте придерживаться HttpClient. Другие шаблоны, такие как WebClient, считаются устаревшими.

Затем заголовки CORS обычно возвращаются с сервера, когда на сервер отправляется вызов OPTIONS. Вы не делаете этого здесь, и вам никогда не придется беспокоиться о подобных вещах внутри программы C#, запущенной с вашего компьютера. Таким образом, вы можете отбросить заголовок контроля доступа.

Данные с URL-адресом формы не являются данными JSON. Это другой способ форматирования данных. Если вы хотите отправить данные JSON, вы должны использовать тип содержимого application/json

Наконец, вы пытаетесь добавить заголовок Authorization. Но в этом нет особого смысла, поскольку вы пытаетесь аутентифицировать себя, чтобы стать авторизованным. Если вы отправите правильное имя пользователя / пароль, вы получите токен-носитель, который вы можете использовать в заголовке Authorization для будущих запросов к указанной службе.

О, и я забыл добавить: всякий раз, когда вы видите ошибку в диапазоне [400,499] (в данном случае «400 - неверный запрос») это означает, что вы отправили что-то не так, и сервер не понимает, что вы пытаетесь сделать. Например: 401 означает, что вы отправили недействительную или отсутствующую информацию авторизации. 400 означает, что ваши данные, вероятно, были искажены.

Но мне нравится ваш вопрос ... Я вижу, что вы делали, и вы пробовали разные вещи.

Загрузите программу под названием Fiddler, если вы хотите увидеть, как работает HTTP. Это отличный инструмент для отладки ваших HTTP-вызовов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...