带有Axios的Oauth 2.0请求失败

时间:2019-03-04 19:31:57

标签: javascript node.js axios

我可以使用PHP中的Oauth 2.0与Yahoo Fantasy API进行交互,但是当我尝试使用Axios HTTP请求库将代码转换为JavaScript时,没有任何响应。我在做什么错了?

首先,这是有效的有效PHP版本:

function refreshAuthorizationToken($token) {

    $consumer_key = "consumerKeyGoesHere";
    $consumer_secret = "myConsumerSecretGoesHere";
    $auth_header = base64_encode($consumer_key . ":" . $consumer_secret);
    $auth_endpoint = "https://api.login.yahoo.com/oauth2/get_token";

    $ch = curl_init();

    $post_values = [
        "redirect_uri" => "oob",
        "grant_type" => "refresh_token",
        "refresh_token" => $token
    ];

    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => $auth_endpoint,
        CURLOPT_POST => 1,
        CURLOPT_HTTPHEADER => array(
        'Authorization: Basic ' . $auth_header,
        'Access-Control-Request-Headers: authorization',
        'Content-Type: application/x-www-form-urlencoded',
        'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'),
        CURLOPT_POSTFIELDS => http_build_query($post_values)
    ));

    $answer = curl_exec($ch);
    $token = json_decode($answer);

    if (!isset($access_token)) {
        return "Error: access token not set."

    }
    else {
        return $token;
    }
}

现在这是无法使用的JavaScript代码:

const consumerKey = `consumerKeyGoesHere`;
const consumerSecret = `consumerSecretGoesHere`;
const authHeader = Buffer.from(`${consumerKey}:${consumerSecret}`, `binary`).toString(`base64`);

async function refreshAuthorizationToken(token) {
    const authEndpoint = `https://api.login.yahoo.com/oauth2/get_token`;

    let response;
    try {
        response = await axios({
            url: authEndpoint,
            method: 'post',
            headers: {
              'Authorization': `Basic ${authHeader}`,
              'Access-Control-Request-Headers': 'authorization',
              'Content-Type': 'application/x-www-form-urlencoded',
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
            },
            data: {
              redirect_uri: 'oob',
              grant_type: 'refresh_token',
              refresh_token: token
            },
            timeout: 1000,
          });
          if (response.data) writeToFile(response.data, authFile, 'w');
          return JSON.parse(response.data);
    } catch (error) {
        console.error(`Error in refreshAuthorizationToken: ${error}`);
    }
}

我尝试使用params而不是data,但是无论我如何尝试捕获错误(尝试了几种不同的排列方式),无论此请求终止了什么,都没有响应。

我以为这可能是HTTPS问题,但是即使我创建具有自签名证书的HTTPS服务器,请求仍然会静默地消失。

有人知道如何解决此问题吗?还是使用Axios / Node正确形成OAuth 2.0客户端刷新令牌请求的示例?

2 个答案:

答案 0 :(得分:0)

请参见documentation中的axios:

  

默认情况下,axios将JavaScript对象序列化为JSON。要改为以application / x-www-form-urlencoded格式发送数据,可以使用以下选项之一。

您正在设置一个Content-Type标头,声称您正在发送application/x-www-form-urlencoded数据,但是您没有做任何文档建议的以这种格式生成数据的事情。


在旁边:

'Access-Control-Request-Headers': 'authorization',

这是一个 response 标头,将其包含在请求中没有任何意义。

答案 1 :(得分:0)

有两个问题-一个,如下面的Quentin所述,如果要使用application/x-www-form-urlencoded(Yahoo API要求),我需要对数据JSON进行字符串化。

第二个问题是我的诺言处理。 refreshAuthorizationToken既不应该异步也不使用await,它应该只返回axios-应该使用async / await的 calling 函数。

工作代码:

const qs = require('qs');
const fs = require('fs');
const axios = require('axios');

const consumerKey = `myConsumerKeyHere`;
const consumerSecret = `myConsumerSecretHere`;
const authHeader = Buffer.from(`${consumerKey}:${consumerSecret}`, `binary`).toString(`base64`);
const authEndpoint = `https://api.login.yahoo.com/oauth2/get_token`;


function writeToFile(data, file, flag) {
    if (flag === null) flag = `a`;
    fs.writeFile(file, data, {flag: flag}, (err) => {
        if (err) {
            console.error(`Error in writing to ${file}: ${err}`);
        }
    });
}

function refreshAuthorizationToken(token) {

    return axios({
        url: authEndpoint,
        method: 'post',
        headers: {
            'Authorization': `Basic ${authHeader}`,
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
        },
        data: qs.stringify({
            redirect_uri: 'oob',
            grant_type: 'refresh_token',
            refresh_token: token
        }),
        timeout: 1000,
        }).catch((error) => {
            console.log(`Some kind of horrible error in refreshAuthorizationToken: ${error}`);
    });

}

async function reload() {
    const returnVal = await refreshAuthorizationToken(credentials.refresh_token); 
    if (returnVal) {
        if (returnVal.data && returnVal.data.access_token) {
            writeToFile(JSON.stringify(returnVal.data), authFile, 'w');
        }
    }
}

reload();