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

使用Spotipy的SpotifyOAuth无法获取用户信息,授权流程异常

问题分析与解决方案

核心问题

  1. ClientCredentials流的局限性:该模式仅用于访问Spotify公开数据,无法获取用户私有信息(如current_user()),必须使用授权码流(SpotifyOAuth),但你当前的代码存在两个关键错误:
    • 每次请求都重新实例化SpotifyOAuth,未复用或存储用户已授权的token,导致每次调用都触发全新的授权流程,Postman因此反复打开授权页面。
    • 视图返回语句JsonResponse(test, safe=False)完全错误,test是函数对象,并非要返回的数据。

修复步骤

1. 扩展用户模型存储Spotify Token

首先需要在用户模型中添加字段,用于保存用户的Spotify授权token(支持过期自动刷新):

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    # 存储Spotify返回的token信息(含access_token、refresh_token等)
    spotify_token = models.JSONField(null=True, blank=True)

2. 新增授权引导与回调视图

单独拆分授权流程,避免每次请求重复触发授权:

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import permissions
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from django.conf import settings

# 引导用户跳转到Spotify授权页面
@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def spotify_auth(request):
    sp_oauth = SpotifyOAuth(
        client_id=settings.SPOTIFY_CLIENT_ID,
        client_secret=settings.SPOTIFY_CLIENT_SECRET,
        redirect_uri=settings.SPOTIPY_REDIRECT_URI,
        # 根据需求添加权限,获取用户信息至少需要user-read-private
        scope="user-read-private user-read-email"
    )
    auth_url = sp_oauth.get_authorize_url()
    return Response({"auth_url": auth_url})

# 接收Spotify授权回调,存储token到用户模型
@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def spotify_callback(request):
    code = request.GET.get('code')
    if not code:
        return Response({"error": "授权码缺失"}, status=400)
    
    sp_oauth = SpotifyOAuth(
        client_id=settings.SPOTIFY_CLIENT_ID,
        client_secret=settings.SPOTIFY_CLIENT_SECRET,
        redirect_uri=settings.SPOTIPY_REDIRECT_URI
    )
    token_info = sp_oauth.get_access_token(code)
    # 将token存入当前用户
    request.user.spotify_token = token_info
    request.user.save()
    return Response({"message": "Spotify授权成功"})

3. 重构原测试视图

复用已存储的token,避免重复授权:

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def test(request):
    # 检查用户是否已完成Spotify授权
    if not request.user.spotify_token:
        return Response({"error": "请先调用/spotify-auth完成授权"}, status=400)
    
    sp_oauth = SpotifyOAuth(
        client_id=settings.SPOTIFY_CLIENT_ID,
        client_secret=settings.SPOTIFY_CLIENT_SECRET,
        redirect_uri=settings.SPOTIPY_REDIRECT_URI
    )
    token_info = request.user.spotify_token
    
    # 检查token是否过期,过期则自动刷新
    if sp_oauth.is_token_expired(token_info):
        token_info = sp_oauth.refresh_access_token(token_info['refresh_token'])
        request.user.spotify_token = token_info
        request.user.save()
    
    # 用有效token初始化Spotipy客户端
    sp = spotipy.Spotify(auth=token_info['access_token'])
    
    # 测试获取公开数据与用户私有数据
    urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
    artist = sp.artist(urn)
    user = sp.current_user()
    
    return Response({
        "artist": artist,
        "current_user": user
    })

关键注意事项

  • 确保SPOTIPY_REDIRECT_URI已在Spotify开发者后台的应用设置中正确配置,且与代码中的地址完全一致。
  • 权限scope需根据实际需求添加,比如获取用户播放列表需额外添加playlist-read-private等权限。
  • Postman测试流程:先调用/spotify-auth获取授权URL,在浏览器打开完成授权后,回调会自动存储token,之后再调用/test即可正常获取用户信息,不会重复弹出授权页面。

内容的提问来源于stack exchange,提问作者Mymy la brute

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:10:29