Authentication Mix-Up: Cookies Causing Unintended Logins

Hello,

I’m working on a Streamlit app deployed on Cloud Run, and I’m encountering a tricky issue with my cookie-based authentication. The problem seems to be how I’m setting and using cookies, leading to users logging in with credentials of previous users.

The Behavior:

  • After a user authenticates, I set a cookie (reauthentication_JADE_token) to facilitate auto-login.
  • Problem: When another user accesses the app, the check_cookies() function finds the existing cookie and logs them in using the previous user’s information.

My Suspicion:

I think I might be misunderstanding how cookies should function within a multi-user Streamlit environment.

Questions:

  1. Cookie Best Practices: How can I effectively use cookies for authentication in a Streamlit app where multiple users might be accessing it concurrently?
  2. Scope and Isolation: Should cookies be user-specific? If so, how do I enforce that isolation in my code?

Any advice or insights on how to resolve this authentication conflict would be greatly appreciated!
Let me know if I should provide more code context.

Here my complete code for more context:

import jwt
import os
import streamlit as st
import extra_streamlit_components as stx
from datetime import datetime, timedelta
from functions.client_cache_functions import init_connection
from bson.objectid import ObjectId

def get_manager():
    return stx.CookieManager()

cookie_manager = get_manager()

cookie_name = 'reauthentication_JADE_token'
cookie_expiry_days = 30
key = os.getenv('JADE_SECRET_KEY')

def _token_decode(token) -> str:
    try:
        return jwt.decode(token, key, algorithms=['HS256'])
    except:
        return False
        
def _token_encode() -> str:
    return jwt.encode(
        payload = {
            'mongo_id': str(st.session_state['current_user']['_id']),
            'exp_date': (datetime.now() + timedelta(days=cookie_expiry_days)).timestamp()
            }, 
        key=key, 
        algorithm='HS256')

def check_cookies():
    token = cookie_manager.get(cookie_name)
    if token is not None:
        token = _token_decode(token)
        if token is not False and token['exp_date'] > datetime.now().timestamp() and 'mongo_id' in token:
            client = init_connection()
            st.session_state["client"] = client
            user = client.usersdb.users.find_one({"_id": ObjectId(token['mongo_id'])}, {"_id": 1, "name": 1, "email": 1, "avatar": 1, "admin": 1, "oauth_id": 1, "user_settings": 1, "stripe_settings": 1, "new_user": 1})

            st.session_state["current_user"] = user
            st.session_state["connected"] = True
            return True
        
    return False

def set_cookies():
    token = _token_encode()
    cookie_manager.set(cookie_name, token,
        expires_at=datetime.now() + timedelta(days=cookie_expiry_days))    
    
def delete_cookies():
    st.query_params.clear()
    cookie_manager.delete(cookie_name)

I up this just in case. I’m sure it’s a stupid mistake easy to fix and it’s critical on my side. Sorry if consider spamming