You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何无法免费使用Spotify Web API?Python调用API获取公开播放列表遇403 Forbidden问题求助

解决Spotify Web API 403 Forbidden(要求Premium)的问题

我刚好遇到过类似的情况,先给你梳理下问题根源和解决办法:

为什么你用Client Credentials Flow会返回403?

你当前用的是client_credentials授权方式,这种方式是无用户上下文的——简单说就是你的应用直接以自己的身份请求API,不需要用户登录。但Spotify在最近的权限调整中,收紧了这种授权模式的访问范围:

  • 之前免费开发者账号用这个模式能访问公开播放列表、搜索等端点,但现在只有关联了Premium账号的应用,才能用Client Credentials Flow访问这些内容;
  • 对于普通免费开发者账号,无用户上下文的请求只能访问有限的基础端点(比如获取艺术家的基本信息),而播放列表曲目、搜索这类操作,必须要有用户(哪怕是免费用户)的授权上下文。

那些旧教程能正常用,大概率是因为当时Spotify还没做这个权限限制。

适合你场景的解决方案:切换到Authorization Code Flow

既然你的用户不一定有Premium,那必须改用授权码流(Authorization Code Flow)——这个模式需要用户登录自己的Spotify账号(免费账号也完全可以),获取带有用户授权上下文的token,这样就能正常访问公开播放列表、搜索等端点了。

修改后的代码示例

首先你得先去Spotify开发者控制台,给你的应用添加一个重定向URI(比如http://localhost:8080/callback,随便填一个能访问的本地地址就行),然后替换下面的代码:

import os
import base64
from requests import post, get
import json
from urllib.parse import urlencode

# 替换成你自己的客户端信息
client_id = "你的客户端ID"
client_secret = "你的客户端密钥"
redirect_uri = "http://localhost:8080/callback"  # 要和开发者控制台设置的一致

def generate_auth_url():
    # 定义需要的权限范围,这里只请求读取公开播放列表的权限
    auth_params = {
        "client_id": client_id,
        "response_type": "code",
        "redirect_uri": redirect_uri,
        "scope": "playlist-read-public"
    }
    return "https://accounts.spotify.com/authorize?" + urlencode(auth_params)

def get_access_token(auth_code):
    auth_string = f"{client_id}:{client_secret}"
    auth_bytes = auth_string.encode("utf-8")
    auth_base64 = str(base64.b64encode(auth_bytes), "utf-8")

    url = "https://accounts.spotify.com/api/token"
    headers = {
        "Authorization": f"Basic {auth_base64}",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    data = {
        "grant_type": "authorization_code",
        "code": auth_code,
        "redirect_uri": redirect_uri
    }
    response = post(url, headers=headers, data=data)
    json_response = json.loads(response.content)
    return json_response["access_token"]

def get_auth_header(token):
    return {"Authorization": f"Bearer {token}"}

def fetch_playlist_tracks(token, playlist_id):
    url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
    headers = get_auth_header(token)
    response = get(url, headers=headers)
    
    if response.status_code == 200:
        return json.loads(response.content)
    else:
        print(f"请求出错:状态码 {response.status_code}")
        print(response.json())
        return None

# 步骤1:生成授权链接,让用户访问并授权
auth_url = generate_auth_url()
print(f"请打开下面的链接,登录你的Spotify账号并授权:\n{auth_url}")

# 步骤2:用户授权后,从浏览器地址栏里复制code参数
auth_code = input("请粘贴授权后地址栏里的code:")

# 步骤3:用code换取访问token
access_token = get_access_token(auth_code)

# 步骤4:调用API获取播放列表内容
playlist_data = fetch_playlist_tracks(access_token, "021tegZzZnT8YEpLr0lC3V")
if playlist_data:
    print("\n播放列表内容:")
    print(json.dumps(playlist_data, indent=2))

几个关键注意点

  • 权限范围(Scope):如果你的应用需要更多功能,比如搜索艺术家,可以添加user-read-recently-playedplaylist-read-collaborative等权限,具体看Spotify API文档里的端点要求;
  • 免费用户兼容:授权码流完全支持免费Spotify用户,只要用户愿意授权你的应用,就能正常访问公开内容;
  • 重定向URI:必须和你在开发者控制台设置的完全一致,否则会出现授权失败的情况。

额外建议

如果你的应用是面向前端的(比如网页App),建议用Authorization Code Flow with PKCE,这种模式不需要在前端暴露客户端密钥,安全性更高。

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

火山引擎 最新活动