Im having problems with the flask session and the Spotify OAuth access_token(Im using Spotipy). It is not storing the users info correctly

I started programming a few months ago and Im starting my first “big” project using python and I’m having trouble handling the info when a user logs in my web app. Even when a different user logs in, it always show my Spotify username and playlist infos. For example, if a user called “James” logs in it shows his profile when he is in the auth_url but when it actually access my webpage “getPlaylists”, all the info shown is mine. The Google/YouTube Oauth part is working perfectly, but Spotify Oauth is not.

I added the test users in the developer dashboard of Spotify but it didnt solve the problem. Any tips on what should be? Am I not handling the session correctly?
I dont know if I should paste all the code here, but most of it is what follows:

import spotipy
from spotipy.oauth2 import SpotifyOAuth

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow, Flow
from google.auth.transport.requests import Request
import google.oauth2.credentials

import json
import os
import os.path

from flask import Flask, request, url_for, session, redirect, render_template
from flask_session import Session

import clientinfo # File containing all the info necessary to login the web APP to the Spotify and youtube APIs


app = Flask(__name__)
if __name__ == "__main__":
    app.run(debug=True)

app.secret_key = os.environ['FLASK_S_KEY']

app.config['SESSION_COOKIE_NAME'] = 'Spotify Cookie'

# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

TOKEN_INFO = "token_info"

@app.after_request
def after_request(response):
    """Ensure responses aren't cached"""
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response


def create_spotify_oauth():
    return SpotifyOAuth(
        client_id = os.environ['SPOTIFY_CLIENT_ID'],
        client_secret = os.environ['SPOTIFY_CLIENT_SECRET'],
        redirect_uri = url_for('redirectSite', _external=True),
        scope = "user-read-private playlist-read-private playlist-read-collaborative",
        show_dialog=True
    )

def get_token():
    token_info = session.get(TOKEN_INFO, None)
    if not token_info:
        raise Exception("Token not found in session")
    
    sp_oauth = create_spotify_oauth()

    if sp_oauth.is_token_expired(token_info):
        token_info = sp_oauth.refresh_access_token(token_info['refresh_token'])
        session[TOKEN_INFO] = token_info
    
    print(f"Token info: {token_info}") # Debug
    return token_info

def credentialscheck():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
    
    json_credentials = session.get('credentials')
    
    if 'credentials' in session:
        dict_credentials = json.loads(json_credentials)
        credentials = google.oauth2.credentials.Credentials.from_authorized_user_info(dict_credentials)
        

        if credentials.expired:
            credentials.refresh(Request())

    else:
        return redirect(url_for('redirectYT'))

# Endpoint Index
@app.route('/', methods=["GET"])
def index():
    if request.method == "GET":
        return render_template("index.html")
    

# Log in user to the web app using Spotify OAuth
@app.route("/login")
def login():
     # Forget any user_id
    session.clear()

    sp_oauth = create_spotify_oauth()
    auth_url = sp_oauth.get_authorize_url()
    return redirect(auth_url)

@app.route("/logout")
def logout():
    session.clear()
    return redirect(url_for("index", _external=True))

# After login, redirect user to the page with the correct authorization token
@app.route("/redirect")
def redirectSite():
    sp_oauth = create_spotify_oauth()
    code = request.args.get("code")
    token_info = sp_oauth.get_access_token(code)
    session[TOKEN_INFO] = token_info

    return redirect(url_for("redirectYT", _external=True))

@app.route("/redirectYT")
def redirectYT():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

   # Create OAuth flow object
    flow = Flow.from_client_secrets_file(
        'client_secrets.json',
        scopes=["https://www.googleapis.com/auth/youtube.force-ssl"])
    flow.redirect_uri = url_for('callback', _external=True)
    authorization_url, state = flow.authorization_url(
        access_type='offline',
        prompt='select_account')
    
    # Save the state so we can verify the request later
    session['state'] = state
    
    return redirect(authorization_url)

@app.route('/callback')
def callback():
    # Verify the request state
    if request.args.get('state') != session['state']:
        raise Exception('Invalid state')
    
    # Create the OAUth flow object
    flow = InstalledAppFlow.from_client_secrets_file(
        'client_secrets.json',
        scopes=["https://www.googleapis.com/auth/youtube.force-ssl"],
        state=session['state'])
    flow.redirect_uri = url_for('callback', _external=True)

    # Exchange the authorization code for an access token
    authorization_response = request.url
    flow.fetch_token(authorization_response=authorization_response)

    # Save credentials to the session
    credentials = flow.credentials
    session['credentials'] = credentials.to_json()

    return redirect(url_for('getPlaylists'))

@app.route('/getPlaylists')
def getPlaylists():
    try: 
       token_info = get_token()
       
    except Exception as e:
       print(f"Exception: {e}")
       return redirect(url_for("login", _external=True))
    
    sp = spotipy.Spotify(auth=token_info['access_token'])
    credentialscheck()
    user = sp.current_user()
    username = user['display_name']
    print(f"User: {username}") # Debug
    
    # Getting all playlists (since the current_user_playlists max limit is 50, we need a 'for' loop)
    allPlaylists = []
    i = 0
    while True:
        fiftyplaylists = sp.current_user_playlists(limit=50, offset=i * 50)['items']
        i += 1
        allPlaylists += fiftyplaylists
        if (len(fiftyplaylists)< 50):
            break

    # Filtering the data we actually need in each playlist and sorting them alphabetically)
    playlists = [{'name': playlist['name'], 'id': playlist['id']} for playlist in allPlaylists]
    playlists.sort(key=lambda x: x['name'])

    return render_template("getPlaylists.html", playlists=playlists, username=username)

I already tried printing the token_info and in the getPlaylist it looks always the same, also the username is always the same. Im afraid Im not storing the token_info of the user correctly, but I cant see another way to fix it.I tried this other option of code I saw here on stackoverflow but its happenning the same using it.

import spotipy
from spotipy.oauth2 import SpotifyOAuth

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow, Flow
from google.auth.transport.requests import Request
import google.oauth2.credentials

import json
import os
import os.path
import time

from flask import Flask, request, url_for, session, redirect, render_template
from flask_session import Session

import clientinfo # File containing all the info necessary to login the web APP to the Spotify and youtube APIs

""" requirements [
    Flask,
    Spotipy,
    OS,
    time,
    clientinfo
]"""

app = Flask(__name__)
if __name__ == "__main__":
    app.run(debug=True)

app.secret_key = os.environ['FLASK_S_KEY']

app.config['SESSION_COOKIE_NAME'] = 'Spotify Cookie'

# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)


@app.after_request
def after_request(response):
    """Ensure responses aren't cached"""
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response


def create_spotify_oauth():
    return SpotifyOAuth(
        client_id = os.environ['SPOTIFY_CLIENT_ID'],
        client_secret = os.environ['SPOTIFY_CLIENT_SECRET'],
        redirect_uri = url_for('redirectSite', _external=True),
        scope = "user-read-private playlist-read-private playlist-read-collaborative",
        show_dialog=True
    )

def credentialscheck():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
    
    json_credentials = session.get('credentials')
    
    if 'credentials' in session:
        dict_credentials = json.loads(json_credentials)
        credentials = google.oauth2.credentials.Credentials.from_authorized_user_info(dict_credentials)
        

        if credentials.expired:
            credentials.refresh(Request())

    else:
        return redirect(url_for('redirectYT'))

# Endpoint Index
@app.route('/', methods=["GET"])
def index():
    if request.method == "GET":
        return render_template("index.html")
    

# Log in user to the web app using Spotify OAuth
@app.route("/login")
def login():
     # Forget any user_id
    session.clear()

    sp_oauth = create_spotify_oauth()
    auth_url = sp_oauth.get_authorize_url()
    return redirect(auth_url)

@app.route("/logout")
def logout():
    session.clear()
    return redirect(url_for("index", _external=True))

# After login, redirect user to the page with the correct authorization token
@app.route("/redirect")
def redirectSite():
    sp_oauth = create_spotify_oauth()
    session.clear()
    code = request.args.get("code")
    token_info = sp_oauth.get_access_token(code)

    session["token_info"] = token_info

    return redirect(url_for("redirectYT", _external=True))

@app.route("/redirectYT")
def redirectYT():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

   # Create OAuth flow object
    flow = Flow.from_client_secrets_file(
        'client_secrets.json',
        scopes=["https://www.googleapis.com/auth/youtube.force-ssl"])
    flow.redirect_uri = url_for('callback', _external=True)
    authorization_url, state = flow.authorization_url(
        access_type='offline',
        prompt='select_account')
    
    # Save the state so we can verify the request later
    session['state'] = state
    
    return redirect(authorization_url)

@app.route('/callback')
def callback():
    # Verify the request state
    if request.args.get('state') != session['state']:
        raise Exception('Invalid state')
    
    # Create the OAUth flow object
    flow = InstalledAppFlow.from_client_secrets_file(
        'client_secrets.json',
        scopes=["https://www.googleapis.com/auth/youtube.force-ssl"],
        state=session['state'])
    flow.redirect_uri = url_for('callback', _external=True)

    # Exchange the authorization code for an access token
    authorization_response = request.url
    flow.fetch_token(authorization_response=authorization_response)

    # Save credentials to the session
    credentials = flow.credentials
    session['credentials'] = credentials.to_json()

    return redirect(url_for('getPlaylists'))

@app.route('/getPlaylists')
def getPlaylists():
    session['token_info'], authorized = get_token(session)
    session.modified = True
    if not authorized:
        print("User not authorized!")
        return redirect('/')
    credentialscheck()

    sp = spotipy.Spotify(auth = session.get('token_info').get('access_token'))
    user = sp.current_user()
    username = user['display_name']
    print(f"User: {username}") # Debug
    
    # Getting all playlists (since the current_user_playlists max limit is 50, we need a 'for' loop)
    allPlaylists = []
    i = 0
    while True:
        fiftyplaylists = sp.current_user_playlists(limit=50, offset=i * 50)['items']
        i += 1
        allPlaylists += fiftyplaylists
        if (len(fiftyplaylists)< 50):
            break

    # Filtering the data we actually need in each playlist and sorting them alphabetically)
    playlists = [{'name': playlist['name'], 'id': playlist['id']} for playlist in allPlaylists]
    playlists.sort(key=lambda x: x['name'])

    return render_template("getPlaylists.html", playlists=playlists, username=username)

def get_token(session):
    token_valid = False
    token_info = session.get("token_info", None)

    if not (session.get('token_info', False)):
        token_valid = False
        return token_info, token_valid
    
    now = int(time.time())
    is_token_expired = session.get('token_info').get('expires_at') - now < 60

    if (is_token_expired):
        sp_oauth = create_spotify_oauth()
        token_info = sp_oauth.refresh_access_token(session.get('token_info').get('refresh_token'))
    
    token_valid = True
    return token_info, token_valid

New contributor

Felipe Firmida is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật