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

使用Spotify API遇Status 401 Unauthorized错误,求解决方案

问题描述

我正在开展一个基于Spotify API的项目,按照示例操作后,调用API文档中的任意功能时均收到「Status 401 message unauthorized」的错误提示。我了解到该问题与token相关,但相关解决方案多涉及JSON,而我目前仍在学习JSON,特此求助。

相关Python代码
import base64
import json
from requests import post, get

# 请替换成你的Spotify客户端ID和密钥
SPOTIPY_CLIENT_ID = "你的客户端ID"
SPOTIPY_CLIENT_SECRET = "你的客户端密钥"

# 获取token的函数
def token():
    """
    获取Spotify API的token,没有它API无法工作。
    你不需要修改这个函数的内容。
    """
    auth_string = f"{SPOTIPY_CLIENT_ID}:{SPOTIPY_CLIENT_SECRET}"
    auth_bytes = auth_string.encode("utf-8")
    auth_encoded = base64.b64encode(auth_bytes)

    url = "https://accounts.spotify.com/api/token"
    headers = {
        "Authorization": f"Basic {auth_encoded.decode('utf-8')}",
        "Content-Type": "application/x-www-form-urlencoded"
        }
    data = {"grant_type": "client_credentials"}
    result = post(url, headers=headers, data=data)
    json_result = json.loads(result.content)
    token = json_result["access_token"]
    return token

# 获取授权头的函数
def get_auth_header(token):
    """
    获取Spotify API的授权头。
    你不需要修改这个函数的内容。
    """
    return {"Authorization": f"Bearer {token}"}

def my_profile():
    """
    获取用户的个人资料。
    """
    token_ = token()
    headers = get_auth_header(token_)
    url = "https://api.spotify.com/v1/me"
    result = get(url, headers=headers)
    return json.loads(result.content)


me = my_profile()
print(me)
问题原因及解决方法

核心问题:授权模式不匹配

你当前用的是**客户端凭证授权(Client Credentials)**获取token,但/v1/me接口需要访问用户的私有数据(个人资料),这种授权模式无法满足需求——客户端凭证模式只能获取Spotify的公开数据(比如公开歌单、歌手信息),没有用户的授权权限,所以API返回401未授权错误。

解决步骤

1. 改用授权码授权流程

要访问用户私有数据,必须使用授权码授权(Authorization Code Flow),流程大致是:

  • 引导用户跳转到Spotify的授权页面,用户登录并同意授权后,会返回一个授权码
  • 用这个授权码换取包含用户权限的access token

2. 简化实现:使用Spotipy库

如果你不想手动处理复杂的授权流程和JSON解析,推荐用spotipy库,它封装了所有Spotify API的操作,包括授权流程:

首先安装库:

pip install spotipy

然后修改代码为:

import spotipy
from spotipy.oauth2 import SpotifyOAuth

# 替换成你的客户端ID、密钥和回调地址(回调地址需要在Spotify开发者后台配置)
SPOTIPY_CLIENT_ID = "你的客户端ID"
SPOTIPY_CLIENT_SECRET = "你的客户端密钥"
SPOTIPY_REDIRECT_URI = "http://localhost:8080/callback"

# 初始化Spotify客户端,请求用户资料权限
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(
    client_id=SPOTIPY_CLIENT_ID,
    client_secret=SPOTIPY_CLIENT_SECRET,
    redirect_uri=SPOTIPY_REDIRECT_URI,
    scope="user-read-private user-read-email"  # 需要的权限,获取个人资料需要这两个
))

# 获取当前用户资料
me = sp.current_user()
print(me)

3. 手动实现授权流程(适合学习)

如果你想手动实现,需要分两步:

第一步:获取授权码

import webbrowser

# 构造授权URL
auth_url = f"https://accounts.spotify.com/authorize?client_id={SPOTIPY_CLIENT_ID}&response_type=code&redirect_uri={SPOTIPY_REDIRECT_URI}&scope=user-read-private user-read-email"
webbrowser.open(auth_url)
# 用户授权后,回调地址会带上code参数,比如http://localhost:8080/callback?code=xxx,复制这个code

第二步:用授权码换取token

def get_token_with_code(code):
    url = "https://accounts.spotify.com/api/token"
    headers = {
        "Authorization": f"Basic {base64.b64encode(f'{SPOTIPY_CLIENT_ID}:{SPOTIPY_CLIENT_SECRET}'.encode()).decode()}",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    data = {
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri": SPOTIPY_REDIRECT_URI
    }
    result = post(url, headers=headers, data=data)
    json_result = json.loads(result.content)
    return json_result["access_token"]

# 替换成你获取到的code
code = "你从回调地址复制的code"
token = get_token_with_code(code)

# 然后调用接口
headers = get_auth_header(token)
result = get("https://api.spotify.com/v1/me", headers=headers)
print(json.loads(result.content))

额外注意点

  • 确保你的Spotify开发者后台已经配置了正确的回调地址,否则授权会失败
  • 处理错误:原代码中如果token请求失败(比如客户端ID错误),直接取json_result["access_token"]会报错,建议加判断:
    result = post(url, headers=headers, data=data)
    if result.status_code != 200:
        print(f"获取token失败:{result.content}")
        return None
    json_result = json.loads(result.content)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:24:54