0

Problem Description

Hello, I have been working on a backend server that I would like to be able to use to handle Spotify sessions for users. I am using Flask, and I found a very helpful example from the Spotipy documentation here.

The problem that I am running into is that the sessions from Flask don't seem to maintain their state in between API calls and I have been going nowhere in my efforts to fix it. Here is my setup:

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"}

Everything within the get method works just fine! I can sign in to spotify and it even generates a uuid and saves it to the session during that method, but every subsequent call to the API after the redirect creates a new session within the session folder. What it boils down to is that I am not sure how to get flask to recognize that it should use the session that was already created.

Fetch Requests from frontend

fetch('http://127.0.0.1:5000/Spotify/', 
        {method: 'GET',
        credentials:'include'})
            .then(response => response.json())
            .then(
                data => {
                    setSignInLink(data["link_url"])
                }
            )

This one works just fine. The link is generated and set in React.

fetch('http://127.0.0.1:5000/Spotify/', 
        {
            method: 'DELETE',
            credentials:'include'
        })

This is the request which makes it clear that the session uuid has not been maintained as the flask server throws an error.

What I have tried to fix this

Ensuring proper CORS management Following the solution given here I set the fetch request from the frontend to enable credentials, but it still was unable to recognize that the request was coming from the same place for the same session.

I really have been struggling here, so any help would be appreciated thank you so much for your time!

jrosne
  • 1

0 Answers0