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

使用Spotify API创建播放列表时持续出现403 Forbidden错误求助

问题分析

你遇到的403 Forbidden错误核心原因是授权模式不对:

  • 你当前用的client_credentials(客户端凭证)授权模式,只能获取访问Spotify公开数据的权限,无法对用户个人账号(比如创建播放列表、修改个人收藏)进行操作。
  • 而Spotify测试网站能创建播放列表,是因为它使用了用户授权后的token,带有操作个人数据的权限。
解决步骤

要创建用户个人播放列表,必须改用Authorization Code Flow授权模式,这是Spotify API中用于操作用户私有数据的标准流程。

1. 准备工作(Spotify开发者后台)

  • 登录你的Spotify开发者账号,进入对应应用的设置页面
  • 在Redirect URIs中添加一个本地重定向地址,比如http://localhost:8080(后续代码会用到)
  • 确认应用的Client ID和Client Secret已保存

2. 修改授权流程代码

替换原来的access_token函数,实现Authorization Code Flow:

import json
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlencode
import webbrowser
from http.server import HTTPServer, BaseHTTPRequestHandler

# 全局变量
CLIENT_ID = '你的Client ID'
CLIENT_SECRET = '你的Client Secret'
REDIRECT_URI = 'http://localhost:8080'
SPOTIFY_EP = 'https://api.spotify.com/v1/'
AUTHORIZE_URL = 'https://accounts.spotify.com/authorize'
TOKEN_URL = 'https://accounts.spotify.com/api/token'
ACCESS_TOKEN = ''

# 处理重定向获取授权码
class AuthHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global ACCESS_TOKEN
        # 提取授权码
        auth_code = self.path.split('code=')[1].split('&')[0]
        
        # 用授权码换访问token
        token_data = {
            'grant_type': 'authorization_code',
            'code': auth_code,
            'redirect_uri': REDIRECT_URI,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET
        }
        token_response = requests.post(TOKEN_URL, data=token_data)
        token_response.raise_for_status()
        token_json = token_response.json()
        ACCESS_TOKEN = token_json['access_token']
        
        # 返回成功提示
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'Authorization successful! You can close this window now.')
        
        # 关闭服务器
        self.server.shutdown()

def get_authorized_token():
    # 请求授权,需要playlist-modify-public权限
    auth_params = {
        'client_id': CLIENT_ID,
        'response_type': 'code',
        'redirect_uri': REDIRECT_URI,
        'scope': 'playlist-modify-public'  # 创建公开播放列表需要的权限,私有则用playlist-modify-private
    }
    auth_url = f"{AUTHORIZE_URL}?{urlencode(auth_params)}"
    
    # 打开浏览器让用户授权
    webbrowser.open(auth_url)
    
    # 启动本地服务器接收重定向
    server = HTTPServer(('localhost', 8080), AuthHandler)
    server.serve_forever()

# 获取授权后的token
get_authorized_token()

3. 修复创建播放列表的代码

原来的create_playlist函数有两个问题:

  • 发送数据时没有用JSON格式(requests的data参数传字典会默认表单编码,而Spotify API要求JSON)
  • 不需要在请求数据里加grant_type

修改后的函数:

def create_playlist(user_id='shakuryonsteward'):
    playlist_url = f"{SPOTIFY_EP}users/{user_id}/playlists"
    payload = {
        'name': "Top 100 Tracks from Birthday",
        'description': "Generated API Playlist as part of Coding Project xP",
        'public': True
    }
    headers = {
        'Authorization': f'Bearer {ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    
    # 用json参数自动序列化并设置正确的Content-Type
    response = requests.post(playlist_url, json=payload, headers=headers)
    response.raise_for_status()
    print("播放列表创建成功:", response.json())
    return response.json()['id']  # 返回播放列表ID,后续可以用来添加歌曲

# 创建播放列表
playlist_id = create_playlist()

4. 补充:添加歌曲到播放列表

如果需要把之前获取的歌曲添加到新播放列表,可以用这个函数:

def add_tracks_to_playlist(playlist_id, track_uris):
    add_url = f"{SPOTIFY_EP}playlists/{playlist_id}/tracks"
    payload = {
        'uris': track_uris
    }
    headers = {
        'Authorization': f'Bearer {ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    response = requests.post(add_url, json=payload, headers=headers)
    response.raise_for_status()
    print("歌曲添加成功")

# 示例:如果之前的spotify_search函数正常,调用它获取歌曲URI后添加
# top100_tracks = spotify_search(ACCESS_TOKEN)
# add_tracks_to_playlist(playlist_id, top100_tracks)
关键注意点
  • 权限范围:根据播放列表是公开还是私有,选择playlist-modify-public或playlist-modify-private,多个权限用空格分隔
  • Token有效期:Authorization Code Flow的访问token会过期,需要用返回的refresh_token刷新,避免重复授权(可以自行添加刷新逻辑)
  • 请求格式:所有操作用户数据的POST/PUT请求,必须用JSON格式发送数据,不能用表单编码

内容的提问来源于stack exchange,提问作者Shakuryon Steward

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:05:22