You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Spotify API交换Access Token时授权失败问题排查求助

Spotify API授权码交换失败的问题排查与修复

先看你代码里的几个核心问题,这些是导致授权失败的直接原因:

1. 提前引用未定义变量

你在获取授权码后直接打印accessToken,但这个变量要等到token请求返回后才会定义,会触发ReferenceError导致程序崩溃。需要把这两行调试日志移到accessToken定义之后。

2. 回调地址不匹配

你设置的redirectUri是https://localhost:3000,但实际回调路由是/callback,Spotify授权时的redirect_uri必须和代码里的完全一致,否则无法正确回调获取授权码。

3. 端口日志与实际监听端口不一致

代码里app.listen(3000),但日志打印的是Listening on port 8888,会误导你访问错误端口,需要统一端口号。

4. Base64编码方式优化

虽然你用了btoa包,但Node.js原生Buffer处理Base64更稳定,无需额外依赖,建议替换。

修正后的完整代码

const express = require('express');
const fetch = require('node-fetch');

const clientId = '6a6ff97f63df4b20a9d58a64991b520a';
const clientSecret = 'c6fb4a3c5ed64c8aa95bb85f7b859f77';
const redirectUri = 'https://localhost:3000/callback'; // 修正回调地址

const app = express();

app.get('/callback', async (req, res) => {
  const code = req.query.code;
  console.log('Received authorization code:', code);

  if (!code) {
    res.send('Authorization failed');
    return;
  }

  console.log('Exchanging authorization code for access token...');

  const authOptions = {
    method: 'POST',
    headers: {
      // 用Node.js原生Buffer替换btoa
      'Authorization': 'Basic ' + Buffer.from(`${clientId}:${clientSecret}`).toString('base64'),
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code: code,
      redirect_uri: redirectUri
    })
  };

  try {
    const response = await fetch('https://accounts.spotify.com/api/token', authOptions);
    const data = await response.json();

    if (data.error) {
      res.send(`Error: ${data.error} - ${data.error_description || ''}`);
      return;
    }
    
    const accessToken = data.access_token;
    const refreshToken = data.refresh_token;
    
    // 移到accessToken定义后打印
    console.log('Received access token:', accessToken);
    console.log(`Refresh Token: ${refreshToken}`);
    
    // 获取用户播放列表
    const playlistsResponse = await fetch('https://api.spotify.com/v1/me/playlists', {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    });
    const playlists = await playlistsResponse.json();
    
    res.json(playlists);

  } catch (error) {
    res.send(`Error: ${error.message}`);
  }
});

app.listen(3000, () => {
  console.log('Listening on port 3000'); // 统一端口日志
  console.log('Open this URL in a browser to authorize:');
  console.log(`https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=playlist-read-private`);
});

额外注意事项

  • 确保Spotify开发者后台设置的Redirect URI和代码里的redirectUri完全一致,包括协议(http/https)和端口号。
  • 不要把clientId和clientSecret硬编码到代码中,建议用环境变量存储,比如process.env.SPOTIFY_CLIENT_ID。
  • 如果本地使用http而非https,需同步修改redirectUri和Spotify后台的配置。

内容的提问来源于stack exchange,提问作者jatin rajani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 14:56:16