调用Spotify API获取当前播放歌曲时出现404无效用户名错误求助
问题原因
你用的是Client Credentials Flow(客户端凭证授权流),这种方式生成的访问令牌不关联具体用户。而/me/player/currently-playing接口需要访问当前用户的播放数据,Spotify无法识别令牌对应的用户身份,因此返回Invalid username的404错误。手动添加用户名到请求头无效,因为该接口是通过令牌自带的用户上下文识别用户,而非手动传入的参数。
解决方法
必须换成Authorization Code Flow(授权码授权流),这个流程需要用户登录Spotify并授权你的应用,生成的令牌会绑定用户身份,才能访问用户相关接口。
修改后的代码实现
import requests import os import base64 import json from urllib.parse import urlencode def get_authorization_url(): # 配置基础参数 client_id = os.environ.get('client_id') redirect_uri = "http://localhost:8000/callback/" scopes = [ 'ugc-image-upload', 'playlist-modify-private', 'playlist-modify-public', 'user-read-currently-playing' ] scope_str = ' '.join(scopes) # 构造用户授权URL params = { 'client_id': client_id, 'response_type': 'code', 'redirect_uri': redirect_uri, 'scope': scope_str, 'show_dialog': True } return f"https://accounts.spotify.com/authorize?{urlencode(params)}" def exchange_code_for_token(authorization_code): client_id = os.environ.get('client_id') client_secret = os.environ.get('client_secret') redirect_uri = "http://localhost:8000/callback/" # 生成Basic认证头 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": authorization_code, "redirect_uri": redirect_uri } response = requests.post(url, headers=headers, data=data) response.raise_for_status() return response.json() def get_currently_playing(token): headers = {'Authorization': f'Bearer {token}'} url = 'https://api.spotify.com/v1/me/player/currently-playing' response = requests.get(url, headers=headers) if response.status_code == 200: response_json = response.json() if response_json.get('is_playing'): track_name = response_json['item']['name'] artist_name = response_json['item']['artists'][0]['name'] album_name = response_json['item']['album']['name'] return f'当前正在播放:{track_name} - {artist_name}(专辑:{album_name})' else: return '当前没有播放任何音乐' elif response.status_code == 204: return '当前没有播放任何音乐' else: print(f"错误详情:{response.json()}") return '无法获取当前播放曲目' # 执行流程 if __name__ == "__main__": # 1. 生成授权URL,引导用户在浏览器中授权 auth_url = get_authorization_url() print(f"请在浏览器中打开以下URL完成授权:\n{auth_url}") authorization_code = input("授权后复制回调URL中的code参数并输入:") # 2. 用授权码交换访问令牌 token_data = exchange_code_for_token(authorization_code) access_token = token_data['access_token'] # 3. 获取当前播放曲目 result = get_currentlyly_playing(access_token) print(result)
额外注意事项
- 回调URL配置:在Spotify开发者控制台的应用设置中,将
http://localhost:8000/callback/添加到「Redirect URIs」列表,否则授权流程会报错。 - 令牌过期处理:授权码流会返回
refresh_token,可利用它在访问令牌过期时自动刷新,避免重复引导用户授权。 - 权限范围:确保授权请求的
scope包含user-read-currently-playing,否则无法访问播放状态接口。
内容的提问来源于stack exchange,提问作者dashgandhi
相关产品推荐
相关产品推荐

