Spotify API bad request on api/token authorization Error: 400
Spotify API bad request on api/token authorization Error: 400
我正在尝试使用 Spotify API 文档页面上的客户端凭证流来授权 spotify api 请求。这是我使用 API
提取的 javascript ES6 格式的代码
const response = await fetch('https://accounts.spotify.com/api/token', {
mode: 'no-cors',
method: 'POST',
headers: {
'Authorization': 'Basic Yzg4OWYzMjM5MjI0NGM4MGIyMzIyOTI5ODQ2ZjZmZWQ6MmUzZTM2YTMzMTM5NDM1Mzk3NzM4ZDMxMTg4MzM0Mjc=',
'Content-type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials'
});
控制台说这是一个错误的请求并且 return 没有任何 JSON。
另一件真正让我感到困惑的事情是,当我使用 POSTMAN 发送请求时 headers 和 body,它 return 正是我想要的(有效)我不明白这与我正在做的有什么不同......?有人可以帮忙吗?
这里还有来自 Javascript Jquery Ajax 邮递员的代码,如果有帮助的话:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://accounts.spotify.com/api/token",
"method": "POST",
"headers": {
"Authorization": "Basic Yzg4OWYzMjM5MjI0NGM4MGIyMzIyOTI5ODQ2ZjZmZWQ6MmUzZTM2YTMzMTM5NDM1Mzk3NzM4ZDMxMTg4MzM0Mjc=",
"Content-Type": "application/x-www-form-urlencoded",
"Cache-Control": "no-cache",
"Postman-Token": "2f93918d-2e8e-4fb0-a168-7e153dd83912"
},
"data": {
"grant_type": "client_credentials"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
这是请求在 DevTools 中的样子
该特定端点不打算在客户端使用。您应该在某些服务器端脚本中使用它。
The Client Credentials flow is used in server-to-server
authentication
另一个暗示它仅用于服务器端的提示是它使用您的 客户端机密 正如其名称所暗示的那样,它应该保密并可以在客户不是很秘密。
因此,从该端点您可以获得访问令牌,然后您可以在客户端使用该令牌向其他 api 端点发出请求,例如 https://api.spotify.com/v1/tracks
现在来谈谈为什么它在您的通话中不起作用。它在邮递员中工作,因为它忽略了 CORS,并且它正确地发送了授权 header。但是在浏览器中,您将 fetch()
请求模式设置为 no-cors
。在这种模式下,只能发送某些 headers 并且 javascript 无法读取返回的响应。
因此,您的请求不会发送授权 header,因为它不是 no-cors 模式中允许的 simple headers 之一。所以你的请求失败了。即使授权通过了,您也无法按照 no-cors 规则阅读响应。
因此,如果您想继续使用客户端凭据流程,您将:
从浏览器向您自己的服务器发出请求。
fetch("http://myserver.com/getToken")
在服务器上,您可以从那里发送所有正确信息的 https://accounts.spotify.com/api/token
请求。然后将返回的访问令牌发送回客户端
//this is assuming a nodejs server environment
var postQuery = 'grant_type=client_credentials ';
var request = require('request');
var express = require('express');
var app = express();
app.get('/getToken', function(req, res){
request({
url: "https://accounts.spotify.com/api/token",
method: "POST",
headers: {
'Authorization': 'Basic YourBase64EncodedCredentials',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postQuery.length
},
body: postQuery
}, function (error, response, data){
//send the access token back to client
res.end(data);
});
});
在对您需要使用的端点的正常获取请求中使用该访问令牌,因为它们是使用正确的 CORS headers
设置的
fetch("http://myserver.com/getToken")
.then(token=>{
//token will be the token returned from your own server side script
//now we can make a new request to the tracks (or any other api)
return fetch("https://api.spotify.com/v1/tracks",{
headers:{
'Authorization': `Bearer ${token}`
}
}).then(r=>r.json())
})
.then(data=>{
//data will be the data returned from tracks api endpoint
});
我正在尝试使用 Spotify API 文档页面上的客户端凭证流来授权 spotify api 请求。这是我使用 API
提取的 javascript ES6 格式的代码 const response = await fetch('https://accounts.spotify.com/api/token', {
mode: 'no-cors',
method: 'POST',
headers: {
'Authorization': 'Basic Yzg4OWYzMjM5MjI0NGM4MGIyMzIyOTI5ODQ2ZjZmZWQ6MmUzZTM2YTMzMTM5NDM1Mzk3NzM4ZDMxMTg4MzM0Mjc=',
'Content-type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials'
});
控制台说这是一个错误的请求并且 return 没有任何 JSON。
另一件真正让我感到困惑的事情是,当我使用 POSTMAN 发送请求时 headers 和 body,它 return 正是我想要的(有效)我不明白这与我正在做的有什么不同......?有人可以帮忙吗?
这里还有来自 Javascript Jquery Ajax 邮递员的代码,如果有帮助的话:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://accounts.spotify.com/api/token",
"method": "POST",
"headers": {
"Authorization": "Basic Yzg4OWYzMjM5MjI0NGM4MGIyMzIyOTI5ODQ2ZjZmZWQ6MmUzZTM2YTMzMTM5NDM1Mzk3NzM4ZDMxMTg4MzM0Mjc=",
"Content-Type": "application/x-www-form-urlencoded",
"Cache-Control": "no-cache",
"Postman-Token": "2f93918d-2e8e-4fb0-a168-7e153dd83912"
},
"data": {
"grant_type": "client_credentials"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
这是请求在 DevTools 中的样子
该特定端点不打算在客户端使用。您应该在某些服务器端脚本中使用它。
The Client Credentials flow is used in server-to-server authentication
另一个暗示它仅用于服务器端的提示是它使用您的 客户端机密 正如其名称所暗示的那样,它应该保密并可以在客户不是很秘密。
因此,从该端点您可以获得访问令牌,然后您可以在客户端使用该令牌向其他 api 端点发出请求,例如 https://api.spotify.com/v1/tracks
现在来谈谈为什么它在您的通话中不起作用。它在邮递员中工作,因为它忽略了 CORS,并且它正确地发送了授权 header。但是在浏览器中,您将 fetch()
请求模式设置为 no-cors
。在这种模式下,只能发送某些 headers 并且 javascript 无法读取返回的响应。
因此,您的请求不会发送授权 header,因为它不是 no-cors 模式中允许的 simple headers 之一。所以你的请求失败了。即使授权通过了,您也无法按照 no-cors 规则阅读响应。
因此,如果您想继续使用客户端凭据流程,您将:
从浏览器向您自己的服务器发出请求。
fetch("http://myserver.com/getToken")
在服务器上,您可以从那里发送所有正确信息的
https://accounts.spotify.com/api/token
请求。然后将返回的访问令牌发送回客户端//this is assuming a nodejs server environment var postQuery = 'grant_type=client_credentials '; var request = require('request'); var express = require('express'); var app = express(); app.get('/getToken', function(req, res){ request({ url: "https://accounts.spotify.com/api/token", method: "POST", headers: { 'Authorization': 'Basic YourBase64EncodedCredentials', 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': postQuery.length }, body: postQuery }, function (error, response, data){ //send the access token back to client res.end(data); }); });
在对您需要使用的端点的正常获取请求中使用该访问令牌,因为它们是使用正确的 CORS headers
设置的fetch("http://myserver.com/getToken") .then(token=>{ //token will be the token returned from your own server side script //now we can make a new request to the tracks (or any other api) return fetch("https://api.spotify.com/v1/tracks",{ headers:{ 'Authorization': `Bearer ${token}` } }).then(r=>r.json()) }) .then(data=>{ //data will be the data returned from tracks api endpoint });