Nodejs - Spotify API 刷新令牌

Nodejs - Spotify API Refresh Token

首先。我以前没有使用过 API。

我遇到的问题是刷新令牌。作为重定向 URI 的查询参数返回的代码似乎每次都需要手动输入。当我获得该身份验证代码时,下面的代码将获得新的访问令牌以及刷新令牌。

我使用的包是 spotify-web-api-node and the code below is a result of following their readme. I have also tried spotify-oauth-refresher,但我对编码太陌生,不知道如何使用它。

我也试过按照 Spotify 自己网站上的指南进行操作。但我似乎无法自己解决这个问题。

希望得到一些指导。谢谢。 希望一切都清楚。

 var scopes = ['user-read-private', 'user-read-email', 'playlist-read-private', 'playlist-modify-private'],
      redirectUri = '<redirect uri>',
      clientId = '<client id>',
      clientSecret = '<client secret>',
      state = '<random string>';
    
    var spotifyApi = new SpotifyWebApi({
      redirectUri: redirectUri,
      clientId: clientId,
      clientSecret: clientSecret
    });
    
    // Create the authorization URL
    var authorizeURL = spotifyApi.createAuthorizeURL(scopes, state);
    
    console.log(authorizeURL);
    
    var credentials = {
      clientId: '<client id>',
      clientSecret: '<client secret>',
      redirectUri: '<redirect uri>'
    };
    
    var spotifyApi = new SpotifyWebApi(credentials);
    
    // The code that's returned as a query parameter to the redirect URI
    var code = 'I HAVE TO MANUALLY PUT THIS IN WHEN THE DURATION RUNS OUT';
    
    // Retrieve an access token and a refresh token
    spotifyApi.authorizationCodeGrant(code).then(
      function(data) {
        console.log('The token expires in ' + data.body['expires_in']);
        console.log('The access token is ' + data.body['access_token']);
        console.log('The refresh token is ' + data.body['refresh_token']);
    
        // Set the access token on the API object to use it in later calls
        spotifyApi.setAccessToken(data.body['access_token']);
        spotifyApi.setRefreshToken(data.body['refresh_token']);
      },
      function(err) {
        console.log('Something went wrong!', err);
      }
    );
    
    // clientId, clientSecret and refreshToken has been set on the api object previous to this call.
    spotifyApi.refreshAccessToken().then(
      function(data) {
        console.log('The access token has been refreshed!');
    
        // Save the access token so that it's used in future calls
        spotifyApi.setAccessToken(data.body['access_token']);
      },
      function(err) {
        console.log('Could not refresh access token', err);
      }
    );

编辑:我已经创建了一个可行的解决方案,并会在有时间时提交我的代码。希望今天。

有关直接来自 Spotify 的 Auth Flow 最佳实践的信息可以在下面的 link 中找到。它包括代码片段,详细说明他们希望您如何以及何时 POST 返回刷新令牌以获取新的访问令牌。

https://developer.spotify.com/documentation/general/guides/authorization/code-flow/

这是他们推荐的端点,用于在您检测到访问令牌已过期或您的数据请求因访问令牌过期而失败时刷新您的令牌。

app.get('/refresh_token', function(req, res) {

  var refresh_token = req.query.refresh_token;
  var authOptions = {
    url: 'https://accounts.spotify.com/api/token',
    headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
    form: {
      grant_type: 'refresh_token',
      refresh_token: refresh_token
    },
    json: true
  };

  request.post(authOptions, function(error, response, body) {
    if (!error && response.statusCode === 200) {
      var access_token = body.access_token;
      res.send({
        'access_token': access_token
      });
    }
  });
});

响应将如下所示:

{
   "access_token": "NgCXRK...MzYjw",
   "token_type": "Bearer",
   "scope": "user-read-private user-read-email",
   "expires_in": 3600,
   "refresh_token": "NgAagA...Um_SHo"
}

TLDR:您检查您的访问令牌是否已过期,如果是,POST refresh-token 接收新的访问令牌,然后可以再次用于获取数据。您还会收到一个新的刷新令牌以及来自此的响应,并且该过程会重新开始。

我设法让它工作的方法是通过下面的代码:

const express = require('express');
const SpotifyWebApi = require('spotify-web-api-node');

var generateRandomString = function(length) {
    var text = '';
    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    for (var i = 0; i < length; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    return text;
};

var scopes = ['user-read-private', 'user-read-email', 'playlist-read-private', 'playlist-modify-private'],
    redirectUri = '<redirect uri>',
    clientId = '<client id>',
    clientSecret = '<client secret>',
    state = generateRandomString(16);

// Setting credentials can be done in the wrapper's constructor, or using the API object's setters.
var spotifyApi = new SpotifyWebApi({
    redirectUri: redirectUri,
    clientId: clientId,
    clientSecret: clientSecret
});

// Create the authorization URL
var authorizeURL = spotifyApi.createAuthorizeURL(scopes, state);

// https://accounts.spotify.com:443/authorize?client_id=5fe01282e44241328a84e7c5cc169165&response_type=code&redirect_uri=https://example.com/callback&scope=user-read-private%20user-read-email&state=some-state-of-my-choice
console.log(authorizeURL);

// --------------------------------

var credentials = {
    clientId: '<client id>',
    clientSecret: '<client secret>',
    redirectUri: '<redirect uri>'
};

var spotifyApi = new SpotifyWebApi(credentials);

var app = express();

app.get('/login', function(req, res) {
    res.redirect(authorizeURL);
});

// The code that's returned as a query parameter to the redirect URI
var code = '<authorization code>'; // this does not need to be updated

// Retrieve an access token and a refresh token
spotifyApi.authorizationCodeGrant(code).then(
    function(data) {
        console.log('The token expires in ' + data.body['expires_in']);
        console.log('The access token is ' + data.body['access_token']);
        console.log('The refresh token is ' + data.body['refresh_token']);

        // Set the access token on the API object to use it in later calls
        spotifyApi.setAccessToken(data.body['access_token']);
        spotifyApi.setRefreshToken(data.body['refresh_token']);
    },
    function(err) {
        console.log('Something went wrong!', err);
    }
);
// --------------------------------------------------
// clientId, clientSecret and refreshToken has been set on the api object previous to this call.
function refreshSpotifyToken() {
    spotifyApi.refreshAccessToken().then(
        function(data) {
            console.log('The access token has been refreshed!');

            // Save the access token so that it's used in future calls
            spotifyApi.setAccessToken(data.body['access_token']);
            console.log('The access token is ' + data.body['access_token']);
            console.log('The token expires in ' + data.body['expires_in']);
        },
        function(err) {
            console.log('Could not refresh access token', err);
        });
};
client.on('ready', () => {
    refreshSpotifyToken();
    setInterval(refreshSpotifyToken, 1000 * 59 * 59);
})