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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:34:43