使用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
相关产品推荐
相关产品推荐

