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

React对接Spotipy后端遇invalid client及数据请求异常求助

Spotipy对接React前端出现invalid client错误排查方案

问题描述

将Spotipy后端对接React前端时,出现Spotipy invalid client错误,但后端单独运行官方示例完全正常。React前端从后端获取页面,回调地址配置为http://127.0.0.1:8080,请求数据时持续出现错误及未定义状态;但直接访问回调重定向URL却能正常获取数据,已配置必要的环境变量。

相关代码:

Python后端代码

import os
from flask import Flask, session, request, redirect
from flask_cors import CORS, cross_origin
from flask_session import Session
import spotipy

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(64)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_FILE_DIR'] = './.flask_session/'
CORS(app)
Session(app)

client_id = os.getenv("SPOTIPY_CLIENT_ID")
client_secret = os.getenv("SPOTIPY_CLIENT_SECRET")
redirect_uri = os.getenv("SPOTIPY_REDIRECT_URI")

@app.route('/')
def index():

    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
    auth_manager = spotipy.oauth2.SpotifyOAuth(scope='user-read-currently-playing playlist-modify-private',
                                               cache_handler=cache_handler,
                                               show_dialog=True)

    if request.args.get("code"):
        # Step 2. Being redirected from Spotify auth page
        auth_manager.get_access_token(request.args.get("code"))
        return redirect('/')

    if not auth_manager.validate_token(cache_handler.get_cached_token()):
        # Step 1. Display sign in link when no token
        auth_url = auth_manager.get_authorize_url()
        return f'<h2><a href="{auth_url}">Sign in</a></h2>'

    # Step 3. Signed in, display data
    spotify = spotipy.Spotify(auth_manager=auth_manager)
    return f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
           f'<a href="/playlists">my playlists</a> | ' \
           f'<a href="/currently_playing">currently playing</a> | ' \
        f'<a href="/current_user">me</a>' 



@app.route('/sign_out')
def sign_out():
    session.pop("token_info", None)
    return redirect('/')


@app.route('/playlists')
def playlists():
    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
    auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
    if not auth_manager.validate_token(cache_handler.get_cached_token()):
        return redirect('/')

    spotify = spotipy.Spotify(auth_manager=auth_manager)
    return spotify.current_user_playlists()


@app.route('/currently_playing')
def currently_playing():
    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
    auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
    if not auth_manager.validate_token(cache_handler.get_cached_token()):
        return redirect('/')
    spotify = spotipy.Spotify(auth_manager=auth_manager)
    track = spotify.current_user_playing_track()
    if not track is None:
        return track
    return "No track currently playing."


@app.route('/current_user')
def current_user():
    cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
    auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
    if not auth_manager.validate_token(cache_handler.get_cached_token()):
        return redirect('/')
    spotify = spotipy.Spotify(auth_manager=auth_manager)
    return spotify.current_user()


if __name__ == '__main__':
    app.run(threaded=True, port=int(os.environ.get("PORT",
                                                   os.environ.get("SPOTIPY_REDIRECT_URI", "8080").split(":")[-1])))

React前端代码截图

React代码截图

排查方向与解决方案

1. 显式传递SpotifyOAuth核心参数

当前代码中创建SpotifyOAuth时未显式传入client_id、client_secret、redirect_uri,虽然Spotipy会尝试读取环境变量,但跨场景下可能出现读取失效的情况。修改所有SpotifyOAuth初始化代码,显式传入参数:

# 示例:index路由中的auth_manager初始化
auth_manager = spotipy.oauth2.SpotifyOAuth(
    client_id=client_id,
    client_secret=client_secret,
    redirect_uri=redirect_uri,
    scope='user-read-currently-playing playlist-modify-private',
    cache_handler=cache_handler,
    show_dialog=True
)

其他路由(如playlists、currently_playing)中的SpotifyOAuth初始化也需要补充这三个参数。

2. 配置CORS支持凭证传递

跨域场景下,Flask-CORS需要允许凭证(Cookie)传递,修改CORS初始化代码:

CORS(app, supports_credentials=True)

同时前端请求需开启withCredentials:

  • 若使用axios:添加axios.defaults.withCredentials = true
  • 若使用fetch:在请求配置中加入credentials: 'include'

3. 调整Session Cookie跨域属性

Flask默认的Session CookieSameSite属性为Lax,跨域请求时不会自动携带。修改Flask配置:

app.config['SESSION_COOKIE_SAMESITE'] = 'None'
# 本地开发可暂时设为False,生产环境需启用HTTPS并设为True
app.config['SESSION_COOKIE_SECURE'] = False

4. 验证Spotify开发者后台回调地址

确保Spotify开发者平台中配置的回调地址与代码中redirect_uri完全一致,包括协议(http/https)、IP/域名、端口,不能存在末尾斜杠差异(比如http://127.0.0.1:8080和http://127.0.0.1:8080/会被视为不同地址)。

5. 检查环境变量加载

在代码中添加日志输出,确认环境变量是否正确加载:

print(f"Client ID: {client_id}")
print(f"Redirect URI: {redirect_uri}")

运行后端时查看控制台输出,确保变量值不为空且正确。

内容的提问来源于stack exchange,提问作者Abraham.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:30:58