无法获取Spotify API刷新令牌:React Native+Supabase开发故障排查
解决Spotify PKCE流程下刷新令牌返回invalid_request的问题
首先,你的代码存在一个致命错误:重复读取Response对象的body。当你第一次调用await response.json()时,响应流已被消费,第二次调用会返回空数据或抛出异常,这会干扰正常逻辑执行,甚至掩盖真实的错误信息。
第一步:修复重复读取响应的问题
修正后的代码会先将响应数据存入变量,再进行后续操作,同时用更可靠的方式构建请求体:
class SpotifyTokenRefreshStrategy implements TokenRefreshStrategy { async refreshTokens(config: RefreshTokenConfig): Promise<void> { const url = "https://accounts.spotify.com/api/token"; const clientId = process.env.EXPO_PUBLIC_SPOTIFY_CLIENT_ID; if (!clientId) { throw new Error("Spotify client ID not found"); } const data = { grant_type: "refresh_token", refresh_token: config.refreshToken, client_id: clientId, }; // 用URLSearchParams替代手动编码,避免特殊字符处理错误 const body = new URLSearchParams(data).toString(); const payload = { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: body, }; try { const response = await fetch(url, payload); // 仅读取一次响应数据并存入变量 const responseData = await response.json(); console.log("Spotify refresh response:", responseData); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}, details: ${JSON.stringify(responseData)}`); } // 在这里处理刷新后的令牌,比如更新到Supabase或本地存储 // 示例:config.setTokens({ accessToken: responseData.access_token, refreshToken: responseData.refresh_token || config.refreshToken }) } catch (error) { console.error("Error refreshing Spotify tokens:", error); throw error; } } }
其他排查方向
- 确认refresh_token有效性:确保该refresh_token是通过PKCE流程获取的,且用户未在Spotify账户中取消应用授权——Spotify的refresh_token虽长期有效,但授权被撤销后会立即失效。
- 检查client_id格式:确认
EXPO_PUBLIC_SPOTIFY_CLIENT_ID环境变量无多余空格或特殊字符,URLSearchParams会自动处理编码,但手动编码可能遗漏特殊字符。 - 验证请求头严格性:确保
Content-Type头严格为application/x-www-form-urlencoded,不要添加额外字符或空格,部分服务器对请求头格式要求苛刻。 - Scope一致性:刷新令牌时无需传递scope,但要保证初始授权的scope包含所需权限,且后续未修改过授权scope。
内容的提问来源于stack exchange,提问作者jwmd
相关产品推荐
相关产品推荐

