Неверный запрос API Spotify при авторизации через API / токены Ошибка: 400 - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь авторизовать api-запросы spotify с помощью потока учетных данных клиента на странице документов API Spotify. Вот мой код в формате javascript ES6 с использованием 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.

Еще одна вещь, которая меня действительно смущает, это то, что когда я отправляю запрос, используя POSTMAN с этими заголовками и этим телом, он возвращает именно то, что я хочу (это работает), я не вижу, как это отличается от того, что я делаю ...? Может ли кто-нибудь помочь, пожалуйста?

Также вот код от почтальона в 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 enter image description here

1 Ответ

0 голосов
/ 09 ноября 2018

Эта конкретная конечная точка не предназначена для использования на стороне клиента. Вы должны использовать его в каком-нибудь серверном скрипте.

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

Поток учетных данных клиента используется в сервер-сервер аутентификации

Еще один намек на то, что он предназначен только для серверной части, заключается в том, что он использует ваш секрет клиента , поскольку его имя подразумевает, что он должен храниться в секрете, и его просмотр на клиенте не является очень секретным. ,

Таким образом, с этой конечной точки вы получаете токен доступа, который затем можете использовать на стороне клиента для отправки запросов к другим конечным точкам API, таким как https://api.spotify.com/v1/tracks

Теперь о том, почему это не работает в ваших звонках. Он работает в почтальоне, потому что игнорирует CORS и правильно отправляет заголовок авторизации. Однако в браузере вы устанавливаете режим запроса fetch() на no-cors. В этом режиме могут быть отправлены только определенные заголовки, а ответ обратно не может быть прочитан JavaScript.

В связи с этим ваш запрос не отправляет заголовок авторизации, так как он не является одним из простых заголовков , разрешенных в режиме no-cors. И поэтому ваш запрос не проходит. Даже если авторизация прошла, вы не смогли бы прочитать ответ в любом случае в соответствии с правилами без правил.

Так что, если вы хотите продолжить использовать поток учетных данных клиента, вы бы:

  1. Из браузера сделайте запрос на свой сервер.

    fetch("http://myserver.com/getToken")
    
  2. На сервере вы затем выполняете запрос 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);
      });    
    });
    
  3. Используйте этот токен доступа в обычном запросе на выборку к конечным точкам, которые необходимо использовать, поскольку они настроены с соответствующими заголовками CORS

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