问题描述
您好,我一直在开发一个后端服务器,我希望能够使用它来处理用户的 Spotify 会话。我正在使用 Flask,我从此处的 Spotipy 文档中找到了一个非常有用的示例。
我遇到的问题是来自 Flask 的会话似乎没有在 API 调用之间保持它们的状态,我一直在努力修复它。这是我的设置:
api.py
from flask import Flask
from flask_session import Session
from flask_restful import Api
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(64)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_FILE_DIR'] = './.flask_session_test/'
api = Api(app)
Session(app)
#the following adds CORS headers to request responses in the app
@app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
response.headers.add('Access-Control-Allow-Credentials', 'true')
response.headers.add('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept, x-auth")
return response
api.add_resource(Spotify, '/Spotify/')
if __name__ == '__main__':
app.run(debug=True, threaded=True)
Spotify.py
from flask import session, request, redirect
from flask_restful import Resource
import spotipy
import os
import uuid
SCOPE = "user-read-currently-playing playlist-modify-private"
#Cache logic follows in order to create sessions for spotify
caches_folder = '../.spotify_caches/'
if not os.path.exists(caches_folder):
#Ensure cache folder exists
os.makedirs(caches_folder)
def session_cache_path():
return caches_folder + session.get('uuid')
class Spotify(Resource):
def get(self):
if not session.get('uuid'):
#Visitor is unknown
session['uuid'] = str(uuid.uuid4())
cache_handler = spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
auth_manager = spotipy.oauth2.SpotifyOAuth(scope=SCOPE, cache_handler=cache_handler, show_dialog=True)
if request.args.get("code"):
auth_manager.get_access_token(request.args.get("code"))
return redirect('http://localhost:3000/spotify')
if not auth_manager.validate_token(cache_handler.get_cached_token()):
#Display sign in link when there is no token or token is not valid
auth_url = auth_manager.get_authorize_url()
return {"link_url":f"{auth_url}"}
def delete(self):
try:
#Problem becomes apparent here when the session_cache_path method cannot get the uuid from the session
os.remove(session_cache_path())
session.clear()
except OSError as e:
return {f'Error {e.strerror} in {e.filename}'}, 404
return {"msg":"Sign out successfull"}
get 方法中的所有内容都可以正常工作!我可以登录到 spotify,它甚至会在该方法期间生成一个 uuid 并将其保存到会话中,但是在重定向之后对 API 的每次后续调用都会在会话文件夹中创建一个新会话。它归结为我不确定如何让烧瓶认识到它应该使用已经创建的会话。
从前端获取请求
fetch('http://127.0.0.1:5000/Spotify/',
{method: 'GET',
credentials:'include'})
.then(response => response.json())
.then(
data => {
setSignInLink(data["link_url"])
}
)
这个工作得很好。链接是在 React 中生成和设置的。
fetch('http://127.0.0.1:5000/Spotify/',
{
method: 'DELETE',
credentials:'include'
})
这个请求清楚地表明会话 uuid 没有被维护,因为烧瓶服务器抛出错误。
我试图解决这个问题
确保正确的 CORS 管理 按照此处给出的解决方案,我设置了来自前端的获取请求以启用凭据,但它仍然无法识别该请求来自同一会话的同一位置。
我真的一直在这里挣扎,所以任何帮助将不胜感激,非常感谢您的宝贵时间!