不同Spotify账号登录后API返回相同Access Token问题求助
问题描述
测试时,我用一个Spotify账号登录页面,成功获取到正确的access code和token。但关闭并重启应用后,在无Cookie的无痕标签页中通过同一登录页面登录新的Spotify账号,却发现Spotify API返回了和第一个用户完全相同的access code和token。
问题原因及解决方案
核心问题是SpotifyOAuth默认会本地缓存授权信息,导致新用户登录时复用了旧的缓存数据。以下是针对性的修复步骤:
1. 禁用SpotifyOAuth本地缓存
在创建SpotifyOAuth实例时添加cache_path=None参数,强制每次授权生成全新会话,避免复用缓存的用户信息:
def create_spotify_oauth(): return SpotifyOAuth( client_id = 'INSERT CLIENT ID', client_secret = 'INSERT CLIENT SECRET', redirect_uri=url_for('redirectPage', _external=True), scope='user-library-read user-read-recently-played user-read-playback-position playlist-read-collaborative user-read-playback-state user-top-read playlist-modify-public user-read-currently-playing user-library-read playlist-read-private playlist-modify-private', cache_path=None # 禁用本地缓存 )
2. 强制显示授权确认对话框
生成授权URL时添加show_dialog=True,确保Spotify每次都让用户选择账号并确认授权,即使用户之前授权过你的应用:
@app.route('/login') def login(): sp_oauth = create_spotify_oauth() auth_url = sp_oauth.get_authorize_url(show_dialog=True) # 强制显示账号选择/授权页 return redirect(auth_url)
3. 清理会话残留信息
在回调路由中,除了清空Flask会话,主动关闭SpotifyOAuth的会话连接,避免残留授权数据干扰:
@app.route('/redirect') def redirectPage(): sp_oauth = create_spotify_oauth() session.clear() sp_oauth._get_session().close() # 清理Spotify会话 code = request.args.get('code') token_info = sp_oauth.get_access_token(code) session[TOKEN_INFO] = token_info return redirect(url_for('profile', _external=True))
4. 修复异常抛出语法
原代码中raise "exception"不符合Python语法,改为标准的异常抛出方式:
def get_token(): token_info = session.get(TOKEN_INFO, None) if not token_info: raise Exception("会话中无token信息") now = int(time.time()) is_expired = token_info['expires_at'] - now < 60 if is_expired: sp_oauth = create_spotify_oauth() token_info = sp_oauth.refresh_access_token(token_info['refresh_token']) return token_info
完整修改后的代码
import spotipy from spotipy.oauth2 import SpotifyOAuth from flask import Flask, request, url_for, session, redirect, render_template import time from os import urandom # App Initialization app = Flask(__name__) # Setup Cookies app.secret_key = urandom(64) app.config['SESSION_COOKIE_NAME'] = 'A Session Cookie' TOKEN_INFO = "token_info" @app.route('/login') def login(): sp_oauth = create_spotify_oauth() auth_url = sp_oauth.get_authorize_url(show_dialog=True) return redirect(auth_url) @app.route('/redirect') def redirectPage(): sp_oauth = create_spotify_oauth() session.clear() sp_oauth._get_session().close() code = request.args.get('code') token_info = sp_oauth.get_access_token(code) session[TOKEN_INFO] = token_info return redirect(url_for('profile', _external=True)) # Universal Functions def create_spotify_oauth(): return SpotifyOAuth( client_id = 'INSERT CLIENT ID', client_secret = 'INSERT CLIENT SECRET', redirect_uri=url_for('redirectPage', _external=True), scope='user-library-read user-read-recently-played user-read-playback-position playlist-read-collaborative user-read-playback-state user-top-read playlist-modify-public user-read-currently-playing user-library-read playlist-read-private playlist-modify-private', cache_path=None ) def get_token(): token_info = session.get(TOKEN_INFO, None) if not token_info: raise Exception("会话中无token信息") now = int(time.time()) is_expired = token_info['expires_at'] - now < 60 if is_expired: sp_oauth = create_spotify_oauth() token_info = sp_oauth.refresh_access_token(token_info['refresh_token']) return token_info if __name__ == '__main__': app.run()
内容的提问来源于stack exchange,提问作者A Simple Coder
相关产品推荐
相关产品推荐

