在 Express.js 上使用 Axios 向 Spotify API 发出 POST 请求时出现错误 400

Posted

技术标签:

【中文标题】在 Express.js 上使用 Axios 向 Spotify API 发出 POST 请求时出现错误 400【英文标题】:Error 400 when making POST request to Spotify API with Axios on Express.js 【发布时间】:2019-08-22 22:47:50 【问题描述】:

在 Express 后端服务器上使用 axios 发出发布请求时,我试图从 Spotify API 检索访问令牌。到目前为止,我一直没有成功。我收到以下错误:

数据: 错误:'unsupported_grant_type', 错误描述: 'grant_type 必须是 client_credentials、authorization_code 或 refresh_token'

我已经尝试将“grant_type”的“data”属性更改为“params”,但仍然无法正常工作。任何建议都会有所帮助。

const express = require('express');
const axios = require('axios');
const dotenv = require('dotenv');
dotenv.config();
const app = express();
const port = 3000;

const client_id = process.env.CLIENT_ID;
const client_secret = process.env.CLIENT_SECRET;

app.get('/spotify-authorization', (req, res) => 
  axios(
    method: 'post',
    url: 'https://accounts.spotify.com/api/token',
    data: 
      grant_type: 'client_credentials'
    ,
    headers: 
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization:
        'Basic ' +
        Buffer.from(client_id + ':' + client_secret).toString('base64')
    
  )
    .then(response => 
      console.log(response.data);
    )
    .catch(error => 
      console.log(error);
    );

  res.send('successful response received!');
);

app.listen(port, () => console.log(`Express app listening on port $port!`));

我希望能够在 Spotify API 的响应中检索访问令牌。请帮忙!

【问题讨论】:

我已经尝试过使用“param”和“params”,但不幸的是收到了同样的错误。 来自文档:grant_type Required. As defined in the OAuth 2.0 specification, this field must contain the value "authorization_code".grant_type: 'client_credentials' 更改为 grant_type: "authorization_code" 根据 Spotify API 文档上的客户端凭据流程,grant_type 必须是“client_credentials”。 这个链接还是不同的? developer.spotify.com/documentation/general/guides/… 是的,这就是链接。我正在查看客户端凭据流。 【参考方案1】:

来自axios 文档:By default, axios serializes javascript objects to JSON. To send data in the application/x-www-form-urlencoded format instead, you can use one of the following options.

对于 Nodejs,您可以使用 querystring 模块,如下所示:

var querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify( foo: 'bar' ));

所以,你可以试试data: querystring.stringify( grant_type: 'client_credentials' )

【讨论】:

我试过了,但我现在收到 400 错误并显示以下消息:data: error: 'invalid_client', error_description: 'Invalid client' 听起来像是身份验证问题,您可以尝试使用Postman 并检查响应代码是401 还是403(使用node 转换为base64,或者您可以在线进行) 所以我尝试了 Postman 并得到了成功的响应(200)。然后,我将 Postman 自己的 base64 编码授权标头版本复制到我的 express.js 文件中的 post 请求中,并且它起作用了。所以这让我相信环境变量有问题。原来我将 .env 文件存储在服务器文件上方的目录中,这阻止了它加载相同的变量。一旦我将它们移到同一目录中,请求就起作用了。非常感谢您的帮助!【参考方案2】:

由于声誉低,我无法发表评论,但 1556089774 的答案应该是公认的答案。自从 Spotify 的 iOS sdk 指向 https://glitch.com/~spotify-token-swap 作为一个不起作用的例子以来,我花了 4 个多小时研究它为什么不起作用。将 stringify 添加到请求的数据部分使其工作:

data: querystring.stringify (
  grant_type: "authorization_code",
  redirect_uri: SPOTIFY_CLIENT_CALLBACK_URL,
  code: authorization_code
)

【讨论】:

以上是关于在 Express.js 上使用 Axios 向 Spotify API 发出 POST 请求时出现错误 400的主要内容,如果未能解决你的问题,请参考以下文章

Express JS cors 中间件无法在浏览器上存储 cookie

vue app axios post data to express 后端接收 undefined

使用颤振客户端向 node.js express api 发出 post 请求

express.js 服务器在正在使用的端口上启动

访问前端代码中express.js中设置的标头

IBM 向 Node.js 捐赠 Express 框架,为 Express 丑闻画上了句号