mkhorasani / Streamlit-Authenticator

A secure authentication module to validate user credentials in a Streamlit application.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error in login() method

jurest82 opened this issue · comments

Description

I have a Streamlit application deployed in AWS Elastic Beanstalk. To authenticate users, my app has been using streamlit-authenticator in version 0.2.1.

My app has been in production environment for a year. I did not have issues during the first eleven months, but recently I have had to re-deploy my app at least once a week, because login() method of stauth.Authenticate() fails constantly. This fail causes that users can't use the app.

Logs

The following logs were extracted from Elastic Beanstalk instance:

Captura de pantalla 2024-02-08 a la(s) 11 31 28 a m

Code

This is my Python code. With this code fragment I allow the user authentication process.

import json
from pathlib import Path

import i18n
import streamlit as st
import streamlit_authenticator as stauth
import yaml
from src.frontend.utilities.config import config


def generate_credentials():
    with open(f'{Path(__file__).parent}/users.json', 'r',
              encoding='utf-8') as users_db:
        users = json.load(users_db)

    with open(f'{Path(__file__).parent}/credentials.yaml',
              'w',
              encoding='utf-8') as user_credentials:
        output = {
            'credentials': {
                'usernames': {}
            },
            'cookie': {
                'expiry_days': 60,
                'key': 'someKeyHere-iRemovedItBecauseOfGithub',
                'name': 'someNameHere-iRemovedItBecauseOfGithub'
            }
        }
        hashed_passwords = stauth.Hasher([user['password']
                                          for user in users]).generate()
        for index, user in enumerate(users):

            output['credentials']['usernames'][user['username']] = {
                'email': user['email'],
                'name': user['name'],
                'password': hashed_passwords[index],
                'role': user.get('role', 'reader')
            }
        yaml.dump(output, user_credentials, allow_unicode=True)


def login(func):

    def main(*args, **kwargs):
        config()

        file_path = Path(__file__).parent / "credentials.yaml"
        with file_path.open() as file:
            auth = yaml.load(file, Loader=yaml.SafeLoader)

        authenticator = stauth.Authenticate(auth['credentials'],
                                            auth['cookie']['name'],
                                            auth['cookie']['key'],
                                            auth['cookie']['expiry_days'])

        name, authentication_status, username = authenticator.login(
            f'{i18n.t("login.login")}', 'main')

        if authentication_status is False:
            st.error(f'{i18n.t("login.correct_your_username_or_password")}')

        if authentication_status is None:
            st.warning(f'{i18n.t("login.enter_your_username_and_password")}')

        if authentication_status:
            st.session_state['username_role'] = auth['credentials'][
                'usernames'][username]['role']
            st.sidebar.markdown(f'**{i18n.t("login.hello")} {name}!**')
            authenticator.logout(f'{i18n.t("login.logout")}', 'sidebar')
            return func(*args, **kwargs)

    return main

Any advice anyone can suggest?

I would appreciate any advice. In the meantime, I'm going to redeploy my app, but first I'll update the streamlit-authenticator dependency!

Update

I took the following steps to fix the error:

  1. According to #124, if I add a time.sleep() before login process, the cookie manager might have enough time to retrieve the authentication cookie, and maybe it should solve the problem. Actually, I added two sleep method invocations, one before login and one after login.
  2. I updated streamlit-authenticator dependency from version 0.2.1 to 0.3.1

I am monitoring app usage to check if this fix the issue

Update 2

The first solution doesn't work. Adding two time.sleep(), one before login() and one after login(), does not fix the error.

Additionally, this error persists after upgrading the streamlit-authenticator dependency from version 0.2.1 to 0.3.1.

I change the expiration of cookies to only 1 day. I hope this helps resolve the issue as I understand it.

Update 3

Unfortunately nothing I do helps resolve the error, my streamlit app suddenly crashes and the logs are as follows:

Captura de pantalla 2024-02-27 a la(s) 11 08 49 a m

I'm exploring alternatives to streamlit-authenticator, such as having a proper authentication process with AWS Cognito (I already have an application fully deployed on AWS and powered by Cognito, my streamlit application is 5% of my application and is the only part that is not fully integrated with Cognito).

However, I prefer to have a quickly workaround before Cognito integration. So I continue researching! I suspect the error is not a streamlit-authentication error, I think that this is a streamlit mistake that it is caused by users when they do very intensive operation in the app

However, I prefer to have a quick solution before Cognito integration. So I keep investigating! I also suspect the error is not a streamlit-authenticator error, I think it is an global streamlit error that is caused by users when they perform a very intensive operation on the application.

Please refer to the latest release v0.3.2.