0

问题描述

您好,我一直在开发一个后端服务器,我希望能够使用它来处理用户的 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 管理 按照此处给出的解决方案,我设置了来自前端的获取请求以启用凭据,但它仍然无法识别该请求来自同一会话的同一位置。

我真的一直在这里挣扎,所以任何帮助将不胜感激,非常感谢您的宝贵时间!

4

0 回答 0