具有Twitch身份验证的具有请求承诺的NodeJS发布请求

时间:2018-10-13 02:46:35

标签: javascript node.js oauth-2.0 twitch request-promise

我正在尝试通过其Twitch登录名对我的应用程序上的用户进行身份验证。我似乎无法正确使用request.post()(使用请求承诺)。我尝试了许多不同的变体,并且通常在服务器日志中得到“未处理的拒绝”。 Twitch API指南为此here。 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指南》所说的,我认为我在将其转换为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>

更新: 该应用程序使用Cloud Functions托管在Firebase上。也许这会影响我的要求?

更新2: 根据此说明:Deployed Firebase Function Cannot Execute HTTP GET to external API?我只能在Firebase付费计划上发出外部API请求。我假设这是我的问题。我将升级到“按需付费”计划(实际上免费提供了许多数据),然后重试一次并将结果发布在这里。

3 个答案:

答案 0 :(得分:0)

我不知道您使用的是哪个库,但是最后一个示例与此版本非常相似:https://www.npmjs.com/package/request

如果是该版本,则问题在于您映射的回调参数不正确。 accessTokenResponse var是响应对象,而不是您想要的JSON。您必须像这样解析身体参数。

function(error, response, body){
    console.log(JSON.parse(body));
}

答案 1 :(得分:0)

我认为您使用请求承诺的方式是错误的。试试这个吧。

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

答案 2 :(得分:0)

已解决。事实证明,我确实需要付费计划(Blaze,即付即用)来访问外部API。我升级了,基本上解决了这个问题。它使我看到了一个新的错误代码:StatusCodeError: 400 - "{\"status\":400,\"message\":\"Parameter redirect_uri does not match registered URI\"},因此我发现我的代码中的重定向URL缺少“ / callback”(Twitch应用程序管理设置上的OAuth重定向URL的末尾带有此“ / 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);
});