Почтовый запрос NodeJS с обещанием запроса для аутентификации Twitch

Я пытаюсь аутентифицировать пользователя в своем приложении через его логин Twitch. Я не могу понять request.post() правильно (используя запрос-обещание). Я пробовал много разных вариантов и обычно получаю «Необработанный отказ» в журналах сервера. Руководство по Twitch API для этого находится здесь< /а>. Ответ POST должен быть в формате JSON. Вот моя последняя версия:

const twitchATParams =
'?client_id=' + twitchAppClientId +
'&client_secret=' + twitchClientSecret +
'&code=' + code +
'&grant_type=authorization_code' +
'&redirect_uri=' + twitchAppRedirect;

request.post(twitchATRequestUrl + twitchATParams)
.then((accessTokenResponse) => {
    const accessToken = accessTokenResponse.access_token;
    console.log('Got an access token: ' + accessToken);
    res.status(200).send('Got an access token: ' + accessToken);
  })
  .catch((error) => {
    res.status(error.statusCode).send(error.error.error_description);
  });

Я также пробовал это:

request.post({
url:     twitchATRequestUrl,
form:    { client_id: twitchAppClientId,
           client_secret: twitchClientSecret,
           code: code,
           grant_type: "authorization_code",
           redirect_uri:  twitchAppRedirect}
}, function(error, accessTokenResponse, body){
  const accessToken = accessTokenResponse.access_token;
  console.log('Got an access token: ' + accessToken);
  res.status(200).send('Got an access token: ' + accessToken);
});

Это то, что мне нужно сделать в Twitch API Guide, я думаю, что у меня проблемы с переводом этого на JavaScript:

POST https://id.twitch.tv/oauth2/token
  ?client_id=<your client ID>
  &client_secret=<your client secret>
  &code=<authorization code received above>
  &grant_type=authorization_code
  &redirect_uri=<your registered redirect URI>

ОБНОВЛЕНИЕ: приложение размещено в Firebase с использованием облачных функций. Может быть, это влияет на мой запрос?

ОБНОВЛЕНИЕ 2: Согласно этому: Развернутая функция Firebase не может выполнить HTTP GET для внешнего API? Я могу выполнять запросы внешнего API только в рамках платного плана Firebase. Я предполагаю, что это моя проблема. Я перейду на план с оплатой по мере использования (который на самом деле предоставляет много данных бесплатно), попробую еще раз и опубликую свои результаты здесь.


person Nick H    schedule 13.10.2018    source источник
comment
Какой модуль запроса вы используете?   -  person Hemadri Dasari    schedule 13.10.2018
comment
Я использую запрос-обещание.   -  person Nick H    schedule 13.10.2018
comment
Я бы посоветовал node-fetch попробовать. за последние 8 лет запрос не смог достаточно надежно стабилизироваться, чтобы я мог его даже рассматривать. постоянно что-то ломает.   -  person GottZ    schedule 13.10.2018


Ответы (3)


Я не знаю, какую библиотеку вы используете, но последний пример очень похож на эту версию: https://www.npmjs.com/package/request.

Если это эта версия, проблема в том, что вы неправильно отображаете параметры своего обратного вызова. Переменная accessTokenResponse — это объект ответа, а не ваш JSON, который вы хотите. Вы должны проанализировать параметр body следующим образом.

function(error, response, body){
    console.log(JSON.parse(body));
}
person roag92    schedule 13.10.2018
comment
Я использую запрос-обещание, но он также должен включать в себя все обычные функции запроса, верно? Я попробовал то, что вы предложили, но все еще получаю ошибку Unhandled Rejection, а также пишет SyntaxError: Неожиданный токен u в JSON в позиции 0 и RequestError: Error: getaddrinfo ENOTFOUND id.twitch.tv id.twitch.tv:443 at new RequestError . Мне кажется, что-то не так с запросом POST на серверы Twitch. - person Nick H; 13.10.2018
comment
Я обновил вопрос, указав в Twitch API Guide информацию об этом POST-запросе, чтобы уточнить. - person Nick H; 13.10.2018
comment
Упомянутая вами ошибка связана с разрешением DNS. Я прочитал в другом комментарии, что вы используете облачные функции, верно? Так что, вероятно, это способ раскрыть облачную функцию, позвольте мне попробовать. - person roag92; 13.10.2018
comment
Nevermind — это ваш текущий план Firebase, чтобы сделать запрос к другому API, вы должны выбрать платный план. stackoverflow.com/questions/42774807/ - person roag92; 13.10.2018

Я думаю, что то, как вы использовали запрос-обещание, неверно. Попробуйте это вместо этого.

var rp = require('request-promise');

Внутренняя функция API:

const twitchATParams =
'?client_id=' + twitchAppClientId +
'&client_secret=' + twitchClientSecret +
'&code=' + code +
'&grant_type=authorization_code' +
'&redirect_uri=' + twitchAppRedirect;


var options = {
    method: 'POST',
    uri: twitchATRequestUrl + twitchATParams,
    /* qs: {
        access_token: 'xxxxx xxxxx' // -> uri + '?access_token=xxxxx%20xxxxx'
    }, */ //you can pass params here too
    json: true // Automatically stringifies the body to JSON
};

rp(options)
    .then(function (response) {
        res.status(200).send('Got an access token: ' + response.accessToken);
    })
    .catch(function (err) {
        // Post failed...
    });
person abe.hd    schedule 13.10.2018
comment
Пробовал и это. По-прежнему получают необработанный отказ и RangeError: неверный код состояния: 0 в ServerResponse.writeHead. Может ли это быть связано с тем, что это приложение размещено в Firebase с использованием облачных функций? Это как-то влияет на запрос или ответ? - person Nick H; 13.10.2018
comment
Вы пытались вызвать API с помощью клиента, такого как Postman? Это сработало, как ожидалось? - person abe.hd; 13.10.2018
comment
Я не знаком с Почтальоном. Я могу вызвать API и получить ответ для первого шага этой аутентификации Oauth, просто у меня нет этого кода в моем примере. Только второй шаг, о котором идет речь в этих вопросах, вызывает у меня вопросы. - person Nick H; 13.10.2018

Решено. Оказывается, мне нужен был платный план (Blaze, pay as you go) для доступа к внешним API. Я обновился, и это в основном решило проблему. Это позволило мне увидеть новый код ошибки: StatusCodeError: 400 - "{\"status\":400,\"message\":\"Parameter redirect_uri does not match registered URI\"}, поэтому я обнаружил, что в моем URL-адресе перенаправления в моем коде отсутствует «/ callback» (URL-адрес перенаправления OAuth в настройках управления приложением Twitch имел это «/ callback» в конце).

Я также смог использовать эти два блока кода для успешного получения токена доступа:

const twitchTokenPayload = {
  client_id: twitchAppClientId,
  client_secret: twitchClientSecret,
  code: code,
  grant_type: 'authorization_code',
  redirect_uri: twitchAppRedirect,
};

request.post(twitchATRequestUrl, { json: twitchTokenPayload })
  .then((accessTokenResponse) => {
    const accessToken = accessTokenResponse.access_token;
    console.log('Got an access token: ' + accessToken);
    res.status(200).send('Got an access token: ' + accessToken);
  })
  .catch((error) => {
    console.log('Caught error: ' + error.error.error_description);
    res.status(error.statusCode).send(error.error.error_description);
  });

И это тоже сработало:

request.post({
url:     twitchATRequestUrl,
form:    { client_id: twitchAppClientId,
           client_secret: twitchClientSecret,
           code: code,
           grant_type: "authorization_code",
           redirect_uri:  twitchAppRedirect}
}, function(error, response, body){
  console.log(JSON.parse(body));
  const jsonStuff = JSON.parse(body);
  const accessToken = jsonStuff.access_token;
  console.log('Got an access token: ' + accessToken);
  res.status(200).send('Got an access token: ' + accessToken);
});
person Nick H    schedule 14.10.2018