Spotify API 对 api/token 授权的错误请求错误:400 [英] Spotify API bad request on api/token authorization Error: 400

查看:45
本文介绍了Spotify API 对 api/token 授权的错误请求错误:400的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Spotify API 文档页面上的客户端凭据流授权 Spotify API 请求.这是我使用 fetch API 的 javascript ES6 格式代码

I am trying to authorize spotify api requests using Client Credentials Flow on the Spotify API Docs page. Here is my code in javascript ES6 format using the fetch API

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

控制台说这是一个错误的请求,不返回任何 JSON.

The console is saying it is a bad request and doesn't return any JSON.

另一件让我感到困惑的事情是,当我使用带有这些标头和正文的 POSTMAN 发送请求时,它返回的正是我想要的(它有效)我看不出这与我正在做的有什么不同……?有人可以帮忙吗?

Another thing that really confuses me is that when I send the request using POSTMAN with those headers and that body, it returns exactly what I want (It works) I don't see how this is different from what I'm doing...? Could anyone please help?

如果这有帮助的话,这里还有来自 postman 的 Javascript Jquery Ajax 代码:

Also here is the code from postman in Javascript Jquery Ajax if this helpls:

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 中的样子

This is what the request looks like in DevTools

推荐答案

那个特定的端点并不打算被客户端使用.您应该在某些服务器端脚本中使用它.

That particular endpoint is not meant to be consumed client side. You are supposed to use it in some server side script.

https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow

客户端凭据流用于服务器到服务器身份验证

The Client Credentials flow is used in server-to-server authentication

它仅用于服务器端的另一个提示是它使用您的客户端机密,顾名思义,它是保密的,并且在客户端上不可见秘密.

Another hint that it is meant to be server side only is that it uses your client secret as its name implies it is meant to be kept secret and having it viewable on the client isn't very secret.

因此,您从该端点获得访问令牌,然后您可以在客户端使用该令牌向其他 api 端点发出请求,例如 https://api.spotify.com/v1/tracks

So from that endpoint you get the access token which you can then use on the client side to make requests to the other api endpoints like https://api.spotify.com/v1/tracks

现在至于为什么它在您的通话中不起作用.它在邮递员中工作,因为它忽略 CORS,并正确发送授权标头.但是在浏览器中,您将 fetch() 请求模式设置为 no-cors.在这种模式下,只能发送某些标头,javascript 无法读取返回的响应.

Now as for why it doesn't work in your calls. It works in postman because it ignores CORS, and it properly sends the authorization header. In the browser however you set the fetch() request mode to no-cors. In this mode only certain headers can be sent AND the response back cannot be read by javascript.

因此,您的请求不会发送授权标头,因为它不是 之一在 no-cors 模式下允许简单的标题.所以你的请求失败了.即使授权通过,您也无法按照 no-cors 规则阅读回复.

Due to this your request does not send the authorization header as it is not one of the simple headers allowed in no-cors mode. And so your request fails. Even if the authorization went through you wouldn't have been able to read the response anyways as per no-cors rules.

因此,如果您想继续使用客户端凭据流程,您可以:

So if you want to continue using the Client Credentials flow you would:

  1. 从浏览器向您自己的服务器发出请求.

  1. From the browser, make a request to your own server.

fetch("http://myserver.com/getToken")

  • 然后在服务器上执行 https://accounts.spotify.com/api/token 请求,从那里发送所有正确的信息.然后将返回的访问令牌发送回客户端

  • On the server you would then do the https://accounts.spotify.com/api/token request from there sending all the correct information. Then send the returned access token back to the client

    //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 标头进行设置

  • Use that access token in a normal fetch request to the endpoints you need to use as they are setup with the proper 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 对 api/token 授权的错误请求错误:400的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆