New Component: Streamlit-Authenticator, a secure authenticaton module to validate user credentials in a Streamlit application

Streamlit-Authenticator

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

Installation

Streamlit-Authenticator is distributed via PyPI:

pip install streamlit-authenticator

Example

Using Streamlit-Authenticator is as simple as importing the module and using it to verify your predefined usersā€™ credentials.

import streamlit as st
import streamlit_authenticator as stauth
  • Initially define your usersā€™ names, usernames, and plain text passwords.
names = ['John Smith','Rebecca Briggs']
usernames = ['jsmith','rbriggs']
passwords = ['123','456']
  • Then use the hasher module to convert the plain text passwords to hashed passwords.
hashed_passwords = stauth.hasher(passwords).generate()
  • Subsequently use the hashed passwords to create an authentication object. Here you will need to enter a name for the JWT cookie that will be stored on the clientā€™s browser and used to reauthenticate the user without re-entering their credentials. In addition, you will need to provide any random key to be used to hash the cookieā€™s signature. Finally, you will need to specify the number of days to use the cookie for, if you do not require passwordless reauthentication, you may set this to 0.
authenticator = stauth.authenticate(names,usernames,hashed_passwords,
    'some_cookie_name','some_signature_key',cookie_expiry_days=30)
  • Then finally render the login module as follows. Here you will need to provide a name for the login form, and specify where the form should be located i.e. main body or sidebar (will default to main body).
name, authentication_status = authenticator.login('Login','main')

  • You can then use the returned name and authentication status to allow your verified user to proceed to any restricted content.
if authentication_status:
    st.write('Welcome *%s*' % (name))
    st.title('Some content')
elif authentication_status == False:
    st.error('Username/password is incorrect')
elif authentication_status == None:
    st.warning('Please enter your username and password')
  • Should you require access to the persistent name and authentication status variables, you may retrieve them through Streamlitā€™s session state using st.session_state[ā€˜nameā€™] and st.session_state[ā€˜authentication_statusā€™]. This way you can use Streamlit-Authenticator to authenticate users across multiple pages.
if st.session_state['authentication_status']:
    st.write('Welcome *%s*' % (st.session_state['name']))
    st.title('Some content')
elif st.session_state['authentication_status'] == False:
    st.error('Username/password is incorrect')
elif st.session_state['authentication_status'] == None:
    st.warning('Please enter your username and password')

Or prompt an unverified user to enter a correct username and password.

Please note that logging out will revert the authentication status to None and will delete the associated reauthentication cookie as well.

Credits

16 Likes

This looks awesome :slight_smile: am looking forward to playing with this!

Donā€™t hesitate to add it to the community-driven Components Tracker so we keep track of it :smiley:

Have a nice day :balloon:
Fanilo

3 Likes

Cheers, will do so!

2 Likes

Hello, on 0.88 of streamlit, and our very simple app slows to a crawl when this is usedā€¦ not sure how to begin debugging the cause. Initial load takes over 2 minutes, and login action takes an additional 2+ minutes.

Hi,

Iā€™m not sure what may be the issue. Have you tried accessing your app on a different browser?

Normally in Chrome, only Edge works at all as an alternative, and itā€™s even slower. Oh well, was hoping for a quick solution, ie updating to the latest streamlit etc., thanks for your quick reply though.

I suspect that it may be due to the cookie manager module that is saving an authentication cookie on your browser. In a future release of this package I will add an argument to disable this feature.

Awesome! Exactly what I was looking for.

Just one issue: When the user successfully login, a ā€œLogoutā€ button appear. Is there any way to remove this button? I wonā€™t need it for my usecase, and it kinda gets in the way of the page layout.

Also, would the website work with 2 simultaneous users, in the case both use the same login/password? What about when 2 simultaneous users use different login/passwords?

Thanks a lot!

Glad you like it!

In a future release, I can add the option of removing the logout button, in the meantime however feel free to modify the source code for the package if you wish to implement this earlier.

There is no problem with having multiple users being logged in at the same time (in different sessions obviously) regardless of whether they have the same password or not. The username must be unique, however.

Cheers!

1 Like

Iā€™ve never done that before, but I am keen to try! What steps should I do to play around with the source code?

Should I clone or fork the repo in Github? (Iā€™m guessing fork?)
And, after Iā€™ve made my changes in the code, how can my streamlit app access it? As Iā€™ve already pip installed streamlit-authenticator, when I write ā€œimport streamlit-authenticatorā€ in my streamlit app, wouldnā€™t it look for the original code? (I know those are basic questions, Iā€™m not a developer myselfā€¦)

Thanks again

Hi people! Iā€™m having problems with the module. Iā€™ve copied almost exactly the code into my IDE and when I try to run it, it gives me this error:

ValueError("Please enter hashed passwords and not plain text passwords into the 'authenticate' module.")
ValueError: Please enter hashed passwords and not plain text passwords into the 'authenticate' module.

Any pointers on how to fix it?

Looks fab :raised_hands: i wonder what it is based on? Just using cookies / cash to store the user data or also working with a database e.g. firebase or something? I did the same with it once, it was kinda hustle so if i could use this auth by just passing my firebase db would be even better!

Best regards
Chris

1 Like

@Francisco_Leal, did you hash the passwords exactly like he did, and passed the hashed_passwods to the authenticartor? (see below)

Hi!! I tried literally copying and pasting it and it worked. I will modify the code to my needs and let you know if the problem persists.

1 Like

Hi again! Iā€™m trying to create a DB and I want to save the passwords already hashed in the DB, but if I try to use the password which was already stored hashed, a ValueError requesting to enter hashed passwords instead of plain text words. Any workaround?

You can clone the repository locally and modify the Streamlit-Authenticator/streamlit_authenticator/ init.py file to remove the logout button located on lines 194 and 199. You can then simply import this file into your script without having to worry about installing it through pip. Just make sure to rename the file as to avoid any confusion with other init files.

Cheers.

Thanks. Yes, it stores cookies on your browser to re-authenticate the user without them having to reenter their credentials each and every time they start a new session. Currently, this module does not use any database systems, however, you can absolutely do so if you wish. You can indeed store the hashed passwords on the DB and cross-check when the user attempts to login. Please feel free to make a pull request on the GitHub repo if and when you add such a feature.

Good luck!

Hey Francisco, can you please make sure that when you are reading the hashed passwords from the DB, they are not in any way being modified i.e. leading or trailing white spaces.

Dear all, please install the latest version of Streamlit-Authenticator v0.1.1, as the issue with having to press the logout button twice has been resolved. Thank you for your patience.

1 Like

Hi, is it possibile to put logout button in different place?
Beat regards,
Ola