Получение ошибки 400: неверный запрос при аутентификации через Twitch.tv API

Я новичок здесь, и я надеюсь, что кто-то может мне помочь. Я пытаюсь подключиться к twitch.tv. Я пытаюсь получить аутентификацию oauth2 на twitch.tv с помощью небольшой программы C#. Я использую запрос аутентификации twitch.tv. Вот мой код C#:

    var loginURL = "https://api.twitch.tv/kraken/oauth2/authorize?
                               response_type=code&"+
                               client_id="+ clientID+"
                               "&redirect_uri=http://localhost&"+
                               "state=TWStreamingStateAuthenticated";                    
    this.richTextBox1.Text = loginURL;
    string code = get_DownLoadString(loginURL);
    this.richTextBox1.Text = code;

Это та часть, которая не работает. Это дает мне Ошибка 400: Неверный запрос.

    WebRequest request = WebRequest.Create("https://api.twitch.tv/kraken/oauth2/token");
    request.Method = "POST";
    string postData = "client_id=" + clientID +
                      "&client_secret=" + clientSecret +
                      "&grant_type=authorization_code" +
                      "&redirect_uri=http://localhost" +
                      "&code=" + code +
                      "&state=TWStreamingStateAuthenticated";

    ASCIIEncoding encoding = new ASCIIEncoding();
    postData = HttpUtility.UrlEncode(postData);            
    byte[] byteArray = encoding.GetBytes(postData);
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = byteArray.Length;
    Stream datatream = request.GetRequestStream();
    datatream.Write(byteArray, 0, byteArray.Length);
    datatream.Close();
    WebResponse respone = request.GetResponse();
    MessageBox.Show(((HttpWebResponse)respone).StatusDescription);

Я надеюсь, что кто-то может помочь мне. А вот и метод Get_DownloadString(string URL).

private static string get_DownLoadString(string URL)
{
    try
    {
        string temp = (new WebClient().DownloadString(URL));
        return temp;
    }
    catch (WebException)
    {
        return null;
    }
}

person Innoszorn    schedule 09.01.2016    source источник


Ответы (1)


Этот код мне не подходит:

    string postData = "client_id=" + clientID +
                      "&client_secret=" + clientSecret +
                      "&grant_type=authorization_code" +
                      "&redirect_uri=http://localhost" +
                      "&code=" + code +
                      "&state=TWStreamingStateAuthenticated";

    ASCIIEncoding encoding = new ASCIIEncoding();
    postData = HttpUtility.UrlEncode(postData);
    byte[] byteArray = encoding.GetBytes(postData);
    // ...

Вы кодируете URL-адресом всю строку пост-данных. Это приводит к преобразованию знаков & и = в данных публикации в %26 и %3d соответственно. Когда удаленный сервер получает эти данные, он просматривает их в поисках знаков & и =, чтобы разделить имена и значения параметров. Конечно, он ничего не найдет, поэтому предположит, что у вас есть одно большое имя параметра без значения. Сервер, вероятно, ожидает значения для каждого из шести параметров, которые вы пытаетесь отправить, но не видит значений ни для одного из них, и это может быть причиной того, что вы получаете ошибку 400 Bad Request.

Вместо URL-кодирования всей строки используйте URL-кодирование значений параметров, которые могут содержать символы, отличные от букв и цифр. Вместо этого я бы попробовал следующее:

    string postData = "client_id=" + HttpUtility.UrlEncode(clientID) +
                      "&client_secret=" + HttpUtility.UrlEncode(clientSecret) +
                      "&grant_type=authorization_code" +
                      "&redirect_uri=" + HttpUtility.UrlEncode("http://localhost") +
                      "&code=" + HttpUtility.UrlEncode(code) +
                      "&state=TWStreamingStateAuthenticated";

    ASCIIEncoding encoding = new ASCIIEncoding();
    byte[] byteArray = encoding.GetBytes(postData);
    // ...

Таким образом, удаленный сервер по-прежнему будет видеть символы & и = и сможет извлекать имена и значения параметров. Поскольку мы закодировали идентификатор клиента, секрет клиента, URL-адрес и код в URL-адресе, любые содержащиеся в них символы, которые могут иметь значение в URL-адресе, не будут иметь этого значения и будут получены удаленным сервером, как предполагалось.

Кроме того, если вы по-прежнему получаете ответ об ошибке 400 Bad Request, попробуйте прочитать содержимое потока ответа, полученного путем вызова GetResponseStream() в ответе. Часто это будет содержать сообщение, которое поможет вам понять, что пошло не так.


Присмотревшись к вашему коду, вы, кажется, неправильно понимаете, как работает аутентификация OAuth. Ваш метод getDownload_String не получит нужный вам код доступа, он получит только HTML-текст страницы входа в Twitch.

Вот как работает аутентификация OAuth:

  1. Ваше приложение отправляет пользователя на URL-адрес для входа, чтобы пользователь мог войти в Twitch.
  2. Затем в веб-браузере пользователь вводит свои учетные данные для входа и отправляет страницу на Twitch.
  3. Затем Twitch API отвечает, перенаправляя веб-браузер пользователя на URL-адрес перенаправления с добавленным кодом. Затем ваше веб-приложение считывает этот код из URL-адреса.

Если ваш код находится в веб-приложении, он сможет ответить на URL-адрес, перенаправленный на шаге 3. В качестве альтернативы вы можете использовать элемент управления WebBrowser (Windows Forms, WPF) для обработки входа в Twitch и обработки события Navigating. Если URL-адрес, на который осуществляется переход, начинается с URL-адреса перенаправления, возьмите код из URL-адреса, отмените навигацию и скройте элемент управления веб-браузером для входа в систему.

Наличие того, что кажется элементом управления RichTextBox, а также ваш комментарий о том, что ваш код является «маленьким приложением C#», заставляет меня думать, что ваш код является приложением Windows Forms или WPF. Если это так, то вам нужно либо:

  • используйте элемент управления WebBrowser, как я описал выше,
  • замените приложение WinForms/WPF веб-приложением или
  • свяжитесь с Twitch, чтобы запросить использование поток паролей (который, кажется, не требует перенаправления), и используйте его вместо этого.
person Luke Woodward    schedule 09.01.2016
comment
Я делаю это, как вы говорите. Но знайте, я получаю 403: запрещено. Но я уверен, что мой clientID и мой clientSecret верны. Потому что я скопировал его со своего Twitch-канала. - person Innoszorn; 10.01.2016
comment
@Innoszorn: я думаю, что это шаг в правильном направлении. Теперь сервер понимает ваш запрос, но отказывает в доступе. Как вы получаете code? Не могли бы вы отредактировать свой вопрос, включив в него метод get_DownLoadString? Кроме того, как упоминалось в последнем абзаце, который я написал, есть ли сообщение в теле ответа? - person Luke Woodward; 10.01.2016
comment
Я включил метод get_DownloadString. Часть кода: request.GetResponse() вызывает Исключение: 403: Запрещено. - person Innoszorn; 10.01.2016
comment
@Innoszorn: ваш метод get_DownloadString вообще не получит код, который вам нужен. Вам нужно будет (а) использовать вместо этого веб-приложение, (б) спросить Twitch, можете ли вы использовать поток паролей, или (в) посмотреть, можете ли вы использовать элемент управления WebBrowser для отображения страницы входа и обработки перенаправлений с помощью Navigating мероприятие. Смотрите мой обновленный ответ. Извиняюсь за то, что не увидел раньше «общую картину» того, что вы делаете: если бы я понял раньше, я мог бы сэкономить вам некоторое время. - person Luke Woodward; 10.01.2016
comment
Спасибо за ваши ответы. Я это попробую. - person Innoszorn; 10.01.2016