mkhorasani / Streamlit-Authenticator

A secure authentication module to validate user credentials in a Streamlit application.
Apache License 2.0
1.38k stars 229 forks source link

session_state["authentication_status"] latency issues #124

Closed wyzdic closed 3 months ago

wyzdic commented 5 months ago

with st.sidebar.container(): with open('config.yaml', encoding='utf-8') as file: config = yaml.load(file, Loader=SafeLoader)

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

if not st.session_state["authentication_status"]: authenticator.login() if st.session_state["authentication_status"]: st.write('here) elif st.session_state["authentication_status"] is False: st.error() elif st.session_state["authentication_status"] is None: st.warning()

When I use this code structure, if I refresh or reopen the page when I am logged in, the login page will appear first, and then it will be rendered as the logged in page again. Checking the data with st.write(session_state["authentication_status"]) reveals that the value is None and then updated to True, which is the problem Now I'm in authenticator=stauth. Adding time.sleep(0.2) to the end of the Authenticate snippet temporarily solves the problem, is there a better solution?

mkhorasani commented 5 months ago

Hi @wyzdic, the issue here is that when you refresh your Streamlit application, all session state variables are reset by default, including the authentication_status variable, so effectively you are logged out when you refresh. However, given that Streamlit-Authenticator stores a reauthentication cookie on your browser, each time you rerun, the cookie is checked against your config file cookie parameters to log you back in automatically. However the implementation is somewhat slow due to the cookie manager taking its time to read the cookie. I like your approach and will reconsider adding it to a future release.

wyzdic commented 4 months ago

Thank you for your reply, I found other problems besides that If I put some other elements after if not st.session_state["authentication_status"]: , when I refresh the page, the elements of these login windows will show up even though I have already entered the page after a successful login Here's a way to deal with this type of problem: if not st.session_state["authentication_status"]: login_img = st.empty() with login_img: do something

if st.session_state["authentication_status"]: if 'login_img' in locals().keys(): login_img.empty() Put the element in st.empty(), check if it exists after successful login, if there is an empty container, this will solve my problem temporarily

mkhorasani commented 4 months ago

Can you please share a short video or gif of the problem?

wyzdic commented 4 months ago

Here is a snippet of code that reproduces the issue `if not st.session_state["authentication_status"]: with open("Animation - 1707212136085.json", 'r') as f: login_main = json.load(f) login_page_columns = st.columns([2.5, 3, 2.5]) with login_page_columns[1]: sac.divider(label='Data', icon='', align='center', color='gray') st_lottie( login_main, key='login-main-left', height=300, width=300, )

    authenticator.login(
        location='main',
        fields={
            'Form name': 'Welcome',
        },
        max_concurrent_users=100,
    )

if st.session_state["authentication_status"]:

with st.sidebar.container():
    sac.divider(
        label='Data',
        icon='',
        align='center',
        color='gray',
        key='maindivider',
    )
    st.write(f'Welcome')
    authenticator.logout()

` When you log in/out normally, everything works fine, but when you're already on the post-login page, when you refresh it, all the widgets that should be displayed on the login screen will appear

mkhorasani commented 3 months ago

Dear all please refer to the latest release v0.3.2.