无法在 node.js 中交换访问令牌的代码。 Mailchimp API

Posted

技术标签:

【中文标题】无法在 node.js 中交换访问令牌的代码。 Mailchimp API【英文标题】:Unable to exchange code for access token in node.js. Mailchimp API 【发布时间】:2018-10-13 04:29:18 【问题描述】:

我正在尝试将 OAuth2 与 Mailchimp API 一起使用,并且我正在按照他们的文档进行操作,但我无法完成第 4 步。在此步骤中,我将我从授权屏幕收到的代码交换为令牌.根据文档,这可以像这样在 curl 中完成:

curl --request POST \
--url 'https://login.mailchimp.com/oauth2/token' \
--data "grant_type=authorization_code&client_id=client_id&client_secret=client_secret&redirect_uri=encoded_url&code=code" \
--include

我试图通过编写以下代码将其转换为在 node.js 上工作:

        var dataString = 'grant_type=authorization_code&client_id=' + clientid + '&client_secret=' + clientsecret + '&redirect_uri=' + encodedurl + '&code=' + url.parse(req.url, true).query.code;

        var options = 
            url: 'https://login.mailchimp.com/oauth2/token',
            method: 'POST',
            data: dataString
        ;

        function callback(error, response, body) 
            if (!error) 
                console.dir(JSON.stringify(body));
            
            else
                console.dir(error); 
            
        

        request(options, callback);

当我提出 request.debug = true 时,我看到我收到 400 错误。不过,发送到控制台的消息是一堆乱码。但是,当我使用这些相同的变量和端点通过 Postman 进行身份验证时,它工作正常,因此问题不在于变量或 API 本身。

我不完全确定我在这里做错了什么。我提出的请求似乎与文档中 curl 所写的几乎相同。那我哪里错了?

【问题讨论】:

【参考方案1】:

嗯,你忘记定义request了吗?

var request = require("request");

【讨论】:

既然您可能已经这样做了,那么您可以查看的另一件事是 Postman 中用于发出请求的代码 sn-p。在 Postman 中,在保存下,您应该会看到“代码”。单击它,然后选择“Node.js 请求” - 然后将脚本中的内容与之进行比较。希望对您有所帮助。【参考方案2】:

终于明白了。问题出在请求的标头中。有两种方法可以解决此问题。首先是使用“表单”而不是“数据”。如果使用“form”选项,请求会自动包含“content-type: x-www-form-urlencoded”标头。

var options = 
    url: 'https://login.mailchimp.com/oauth2/token',
    method: 'POST',
    form: dataString
;

我不确定在使用“数据”选项时使用什么标头,或者根本没有声明内容类型。无论哪种方式,如果您选择继续使用“数据”选项,您可以手动声明一个内容类型标头。这是第二种可能的解决方案。

var options = 
    url: 'https://login.mailchimp.com/oauth2/token',
    method: 'POST',
    headers: 
     'Content-Type': 'application/x-www-form-urlencoded' ,
    body: dataString
;

【讨论】:

【参考方案3】:

经过多次尝试,我想通了。您只能使用一次代码。因此,请确保您只使用一次从重定向 URI 获得的代码。

使用新代码使用此代码

const dataString = "grant_type=authorization_code&client_id="+client_id+"&client_secret="+client_secret+"&redirect_uri="+redirect_uri+"&code="+req.body.code
    var options = 
        url: 'https://login.mailchimp.com/oauth2/token',
        method: 'POST',
        headers:
        
          'Content-Type': 'application/x-www-form-urlencoded',
        ,
        form: dataString
    ;
    function callback(error, response, body) 
      if (!error) 
        let str = JSON.stringify(body)
        res.setHeader("Content-Type", "application/json; charset=utf-8")
        res.send(body)
      
      else
        console.dir(error);
        res.send(error)
      

    
    request(options, callback);

【讨论】:

以上是关于无法在 node.js 中交换访问令牌的代码。 Mailchimp API的主要内容,如果未能解决你的问题,请参考以下文章

Node JS试图将访问令牌分配给变量

为啥使用 JWT 而不是在 DB 中存储令牌来授权 Node.js 中的访问令牌?

Istio authservice oidc 无法交换访问令牌的授权码

Rails Google Client API - 无法用刷新令牌交换访问令牌

Node.js 护照 OAuth 2.0 身份验证:存储访问和刷新令牌的位置

在 Oauth OpenID - 授权代码授予类型中,我们将在哪里将“代码”交换为“访问令牌”,为啥?