mkhorasani / Streamlit-Authenticator

A secure authentication module to validate user credentials in a Streamlit application.
Apache License 2.0
1.37k stars 229 forks source link
authentication python streamlit streamlit-component

Streamlit Authenticator logo

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

Downloads Downloads Downloads


To learn more please refer to my book Web Application Development with Streamlit.

Installation

Streamlit-Authenticator is distributed via PyPI:

pip install streamlit-authenticator

Example

Using Streamlit-Authenticator is as simple as importing the module and calling it to verify your predefined users' credentials.

import streamlit as st
import streamlit_authenticator as stauth

1. Creating a configuration file

credentials:
  usernames:
    jsmith:
      email: jsmith@gmail.com
      failed_login_attempts: 0 # Will be managed automatically
      logged_in: False # Will be managed automatically
      name: John Smith
      password: abc # Will be hashed automatically
    rbriggs:
      email: rbriggs@gmail.com
      failed_login_attempts: 0 # Will be managed automatically
      logged_in: False # Will be managed automatically
      name: Rebecca Briggs
      password: def # Will be hashed automatically
cookie:
  expiry_days: 30
  key: some_signature_key # Must be string
  name: some_cookie_name
pre-authorized:
  emails:
  - melsby@gmail.com

_Please note that the 'loggedin' field corresponding to each user's log-in status will be added automatically.

2. Creating a login widget

import yaml
from yaml.loader import SafeLoader

with open('../config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

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

Authenticate

Parameters:

  • credentials: dict
    • Provides the usernames, names, passwords, and emails, and other user data.
  • cookie_name: str
    • Specifies the name of the re-authentication cookie stored on the client's browser for password-less re-authentication.
  • cookie_key: str
    • Specifies the key that will be used to hash the signature of the re-authentication cookie.
  • cookie_expiry_days: float, default 30.0
    • Specifies the number of days before the re-authentication cookie automatically expires on the client's browser.
  • pre-authorized: list, default None
    • Provides the list of emails of unregistered users who are authorized to register.
  • validator: object, default None
    • Provides a validator object that will check the validity of the username, name, and email fields.
authenticator.login()

Authenticate.login

Parameters:

  • location: str, {'main', 'sidebar'}, default 'main'
    • Specifies the location of the login widget.
  • max_concurrent_users: int, default None
    • Limits the number of concurrent users. If not specified there will be no limit to the number of users.
  • max_login_attempts: int, default None
    • Limits the number of failed login attempts. If not specified there will be no limit to the number of failed login attempts.
  • fields: dict, default {'Form name':'Login', 'Username':'Username', 'Password':'Password', 'Login':'Login'}
    • Customizes the text of headers, buttons and other fields.
  • clear_on_submit: bool, default False
    • Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.

      Returns:

    • str
    • Name of the authenticated user.
    • bool
    • Status of authentication, None: no credentials entered, False: incorrect credentials, True: correct credentials.
    • str
    • Username of the authenticated user.

3. Authenticating users

if st.session_state["authentication_status"]:
    authenticator.logout()
    st.write(f'Welcome *{st.session_state["name"]}*')
    st.title('Some content')
elif st.session_state["authentication_status"] is False:
    st.error('Username/password is incorrect')
elif st.session_state["authentication_status"] is None:
    st.warning('Please enter your username and password')

Authenticate.logout

Parameters:

  • button_name: str, default 'Logout'
    • Customizes the button name.
  • location: str, {'main', 'sidebar','unrendered'}, default 'main'
    • Specifies the location of the logout button. If 'unrendered' is passed, the logout logic will be executed without rendering the button.
  • key: str, default None
    • Unique key that should be used in multi-page applications.

4. Creating a reset password widget

if st.session_state["authentication_status"]:
    try:
        if authenticator.reset_password(st.session_state["username"]):
            st.success('Password modified successfully')
    except Exception as e:
        st.error(e)

Authenticate.reset_password

Parameters:

  • username: str
    • Specifies the username of the user to reset the password for.
  • location: str, {'main', 'sidebar'}, default 'main'
    • Specifies the location of the reset password widget.
  • fields: dict, default {'Form name':'Reset password', 'Current password':'Current password', 'New password':'New password', 'Repeat password': 'Repeat password', 'Reset':'Reset'}
    • Customizes the text of headers, buttons and other fields.
  • clear_on_submit: bool, default False
    • Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.

      Returns::

    • bool
    • Status of resetting the password.

Please remember to update the config file (as shown in step 9) after you use this widget.

5. Creating a new user registration widget

try:
    email_of_registered_user, username_of_registered_user, name_of_registered_user = authenticator.register_user(pre_authorization=False)
    if email_of_registered_user:
        st.success('User registered successfully')
except Exception as e:
    st.error(e)

Authenticate.register_user

Parameters:

  • location: str, {'main', 'sidebar'}, default 'main'
    • Specifies the location of the register user widget.
  • pre-authorization: bool, default True
    • Specifies the pre-authorization requirement, True: user must be pre-authorized to register, False: any user can register.
  • domains: list, default None
    • Specifies the required list of domains a new email must belong to i.e. ['gmail.com', 'yahoo.com'], list: the required list of domains, None: any domain is allowed.
  • fields: dict, default {'Form name':'Register user', 'Email':'Email', 'Username':'Username', 'Password':'Password', 'Repeat password':'Repeat password', 'Register':'Register'}
    • Customizes the text of headers, buttons and other fields.
  • clear_on_submit: bool, default False
    • Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.

      Returns:

    • str
    • Email associated with the new user.
    • str
    • Username associated with the new user.
    • str
    • Name associated with the new user.

Please remember to update the config file (as shown in step 9) after you use this widget.

6. Creating a forgot password widget

try:
    username_of_forgotten_password, email_of_forgotten_password, new_random_password = authenticator.forgot_password()
    if username_of_forgotten_password:
        st.success('New password to be sent securely')
        # The developer should securely transfer the new password to the user.
    elif username_of_forgotten_password == False:
        st.error('Username not found')
except Exception as e:
    st.error(e)

Authenticate.forgot_password

Parameters

  • location: str, {'main', 'sidebar'}, default 'main'
    • Specifies the location of the forgot password widget.
  • fields: dict, default {'Form name':'Forgot password', 'Username':'Username', 'Submit':'Submit'}
    • Customizes the text of headers, buttons and other fields.
  • clear_on_submit: bool, default False
    • Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.

      Returns:

    • str
    • Username associated with the forgotten password.
    • str
    • Email associated with the forgotten password.
    • str
    • New plain text password that should be transferred to the user securely.

Please remember to update the config file (as shown in step 9) after you use this widget.

7. Creating a forgot username widget

try:
    username_of_forgotten_username, email_of_forgotten_username = authenticator.forgot_username()
    if username_of_forgotten_username:
        st.success('Username to be sent securely')
        # The developer should securely transfer the username to the user.
    elif username_of_forgotten_username == False:
        st.error('Email not found')
except Exception as e:
    st.error(e)

Authenticate.forgot_username

Parameters

  • location: str, {'main', 'sidebar'}, default 'main'
    • Specifies the location of the forgot username widget.
  • fields: dict, default {'Form name':'Forgot username', 'Email':'Email', 'Submit':'Submit'}
    • Customizes the text of headers, buttons and other fields.
  • clear_on_submit: bool, default False
    • Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.

      Returns:

    • str
    • Forgotten username that should be transferred to the user securely.
    • str
    • Email associated with the forgotten username.

8. Creating an update user details widget

if st.session_state["authentication_status"]:
    try:
        if authenticator.update_user_details(st.session_state["username"]):
            st.success('Entries updated successfully')
    except Exception as e:
        st.error(e)

Authenticate.update_user_details

Parameters

  • username: str
    • Specifies the username of the user to update user details for.
  • location: str, {'main', 'sidebar'}, default 'main'
    • Specifies the location of the update user details widget.
  • fields: dict, default {'Form name':'Update user details', 'Field':'Field', 'Name':'Name', 'Email':'Email', 'New value':'New value', 'Update':'Update'}
    • Customizes the text of headers, buttons and other fields.
  • clear_on_submit: bool, default False
    • Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.

      Returns:

    • bool
    • Status of updating the user details.

Please remember to update the config file (as shown in step 9) after you use this widget.

9. Updating the configuration file

with open('../config.yaml', 'w') as file:
    yaml.dump(config, file, default_flow_style=False)