Spotipy切换用户无效:Django开发Spotify统计应用遇数据异常
问题解决:Spotify统计应用切换用户后数据不更新
核心原因
你遇到的问题和spotipy.util.prompt_for_user_token()的机制直接相关:
- 这个方法是为单用户脚本场景设计的,它会把用户token缓存到本地文件(默认是
.cache-{username})。如果你的开发环境中所有请求共享同一缓存,或者缓存没有按用户正确区分,就会一直复用第一个授权用户的token,导致所有用户都显示同一份数据。 - 当前实现完全不适合多用户的Django web应用——它在服务器端尝试触发授权流程,而正确的做法应该是让前端用户自己走OAuth2授权码流程,把每个用户的token单独存储。
- 你猜测的
REDIRECT_URI不是直接问题,但当前的授权流程逻辑错误才是根源。
修复方案
1. 替换prompt_for_user_token,改用标准OAuth2授权流程
多用户web应用必须让用户自主授权,把每个用户的token存在各自的session或数据库中,不能依赖本地缓存。以下是完整的视图改造代码:
from django.shortcuts import redirect, render from django.conf import settings from django.contrib.auth.decorators import login_required import spotipy from spotipy.oauth2 import SpotifyOAuth # 引导用户跳转到Spotify授权页面 @login_required def spotify_auth(request): sp_oauth = SpotifyOAuth( client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, redirect_uri=settings.REDIRECT_URI, # 必须和Spotify后台配置完全一致,比如http://localhost:8080/spotify/callback scope=settings.SCOPE, show_dialog=True # 强制显示账号选择界面,避免浏览器自动登录旧账号 ) auth_url = sp_oauth.get_authorize_url() return redirect(auth_url) # Spotify授权回调,获取并存储token @login_required def spotify_callback(request): sp_oauth = SpotifyOAuth( client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, redirect_uri=settings.REDIRECT_URI, scope=settings.SCOPE ) code = request.GET.get('code') token_info = sp_oauth.get_access_token(code) # 将token存入当前用户的session request.session['spotify_token'] = token_info return redirect('recents') # 跳回最近播放页面 # 最近播放数据展示视图 @login_required def recents(request): token_info = request.session.get('spotify_token') if not token_info: # 无token时引导用户授权 return redirect('spotify_auth') # 检查token是否过期,自动刷新 sp_oauth = SpotifyOAuth( client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, redirect_uri=settings.REDIRECT_URI, scope=settings.SCOPE ) if sp_oauth.is_token_expired(token_info): token_info = sp_oauth.refresh_access_token(token_info['refresh_token']) request.session['spotify_token'] = token_info session = spotipy.Spotify(auth=token_info['access_token']) recents = session.current_user_recently_played(limit=8) return render(request, 'stats/recents.html', { "recents": recents["items"] })
2. 配置Spotify开发者后台
- 确保
REDIRECT_URI和你在Spotify开发者后台配置的地址完全一致(包括协议、域名、端口、路径)。 - 确认应用的权限范围(
SCOPE)包含user-read-recently-played。
3. 清理旧缓存
删除项目目录下所有.cache-*格式的文件,这些是之前prompt_for_user_token生成的旧token缓存,会干扰新流程。
额外优化建议
- 不要用
first_name存储Spotify用户名,建议给User模型新增spotify_username字段,或者新建SpotifyUser关联模型,专门存储用户的Spotify ID、token等信息,避免和Django默认用户字段混淆。 - 生产环境中,建议把token存入数据库而非session,避免session过期导致用户重复授权。
内容的提问来源于stack exchange,提问作者Hadi Zorkot
相关产品推荐
相关产品推荐

