streamlit-authenticator

repository·main·Indexed 24 days ago

https://github.com/mkhorasani/streamlit-authenticator

A secure authentication module for Streamlit applications to manage user access and authentication workflows. It provides features for user login, registration, password resets, and forgotten username retrieval. The library supports YAML-based configuration for credentials and cookies, password hashing via stauth.Hasher, and guest login via OAuth2 for Google and Microsoft.

Tokens
2.7K
Snippets
12
Records
12
Agent score
35%

What's inside streamlit-authenticator

  1. Save changes to the config file

    main

    Whenever a widget modifies user data (registration, password reset, user details update), you must manually save the updated config dictionary back to your YAML file to persist the changes.

    with open('../config.yaml', 'w') as file:
        yaml.dump(config, file, default_flow_style=False, allow_unicode=True)
  2. Authenticate users and handle session state

    main

    After calling the login widget, check st.session_state to verify the user's status. Use the keys 'authentication_status', 'name', 'username', and 'roles' to control access to content. You can also use authenticator.logout() to end the session.

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

    main

    To set up authentication, load your YAML config and instantiate the stauth.Authenticate class.

    If you have a large number of users, it is recommended to pre-hash passwords using stauth.Hasher.hash_passwords(config['credentials']) and set auto_hash=False in the Authenticate constructor.

    Important: In multi-page applications, you must pass the authenticator object to every page as a session state variable.

    import yaml
    from yaml.loader import SafeLoader
    import streamlit_authenticator as stauth
    
    with open('../config.yaml') as file:
        config = yaml.load(file, Loader=SafeLoader)
    
    # Optional: Pre-hash passwords for performance
    # stauth.Hasher.hash_passwords(config['credentials'])
    
    authenticator = stauth.Authenticate(
        config['credentials'],
        config['cookie']['name'],
        config['cookie']['key'],
        config['cookie']['expiry_days']
    )
  4. Configure the YAML config file

    main

    Create a YAML configuration file to manage user credentials and cookie settings. The file should include cookie settings (expiry, key, name), credentials (usernames, emails, names, passwords, and optional roles), and optional sections for oauth2 (Google/Microsoft) and pre-authorized emails.

    Note: Plain text passwords in this file will be hashed automatically by the library. You must update this file whenever its contents are modified by widgets (e.g., after registration or password resets).

    cookie:
      expiry_days: 30
      key: # To be filled with any string
      name: # To be filled with any string
    credentials:
      usernames:
        jsmith:
          email: jsmith@gmail.com
          failed_login_attempts: 0
          first_name: John
          last_name: Smith
          logged_in: False
          password: abc
          roles:
          - admin
          - editor
          - viewer
        rbriggs:
          email: rbriggs@gmail.com
          failed_login_attempts: 0
          first_name: Rebecca
          last_name: Briggs
          logged_in: False
          password: def
          roles:
          - viewer
    oauth2: # Optional
      google:
        client_id: # To be filled
        client_secret: # To be filled
        redirect_uri: # URL to redirect to after OAuth2 authentication
      microsoft:
        client_id: # To be filled
        client_secret: # To be filled
        redirect_uri: # URL to redirect to after OAuth2 authentication
        tenant_id: # To be filled
    pre-authorized: # Optional
      emails:
      - melsby@gmail.com
  5. Create a guest login widget with OAuth2

    main

    Use authenticator.experimental_guest_login to allow non-registered users to log in via Google or Microsoft. This requires OAuth2 configuration (client ID, secret, etc.) to be present in your config file.

    try:
        authenticator.experimental_guest_login('Login with Google',
                                           provider='google',
                                           oauth2=config['oauth2'])
        authenticator.experimental_guest_login('Login with Microsoft',
                                           provider='microsoft',
                                           oauth2=config['oauth2'])
    except Exception as e:
        st.error(e)
  6. Handle forgotten usernames

    main

    Use authenticator.forgot_username() to allow users to retrieve their username via their email. The method returns the forgotten username and the associated email.

    try:
        username_of_forgotten_username, \
        email_of_forgotten_username = authenticator.forgot_username()
        if username_of_forgotten_username:
            st.success('Username to be sent securely')
        elif username_of_forgotten_username == False:
            st.error('Email not found')
    except Exception as e:
        st.error(e)
  7. Reset a user's password

    main

    Logged-in users can change their password using authenticator.reset_password(username). This returns a boolean indicating success.

    if st.session_state.get('authentication_status'):
        try:
            if authenticator.reset_password(st.session_state.get('username')):
                st.success('Password modified successfully')
        except Exception as e:
            st.error(e)
  8. Update user details

    main

    Logged-in users can update their name and/or email using authenticator.update_user_details(username). This automatically updates the credentials dictionary and the re-authentication cookie.

    if st.session_state.get('authentication_status'):
        try:
            if authenticator.update_user_details(st.session_state.get('username')):
                st.success('Entries updated successfully')
        except Exception as e:
            st.error(e)
  9. Register a new user

    main

    Allow users to sign up using authenticator.register_user(). You can restrict registration to a list of pre-authorized emails using the pre_authorized parameter. The method returns the new user's email, username, and name.

    try:
        email_of_registered_user, \
        username_of_registered_user, \
        name_of_registered_user = authenticator.register_user(pre_authorized=config['pre-authorized']['emails'])
        if email_of_registered_user:
            st.success('User registered successfully')
    except Exception as e:
        st.error(e)
  10. Handle forgotten passwords

    main

    Use authenticator.forgot_password() to allow users to generate a new random password. The method returns the username, email, and the new plain text password. You are responsible for securely transferring this new password to the user (e.g., via email).

    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')
        elif username_of_forgotten_password == False:
            st.error('Username not found')
    except Exception as e:
        st.error(e)