A simple username/password database authentication solution for Streamlit

Overview

Simple Authentication for Streamlit Apps

A simple username/password database authentication solution for Streamlit

Arvindra Sehmi, CloudOpti Ltd. | Website | LinkedIn

Updated: 31 August, 2021


TL;DR: This is a simple username/password login authentication solution using a backing database. Both SQLite and Airtable are supported.

Quick start

To get started immediately with a SQLite database, follow these steps:

  1. Clone this repo

  2. Copy the sample environment settings file env.sample to .env

  3. Install requirements

    pip install -r requirements.txt

  4. Initialize the SQLite database and create some users (including at least one super user)

    streamlit run admin.py

  5. Finally, run the test application

    streamlit run app.py

Introduction

This is not an identity solution, it's a simple username/password login authentication solution using a backing database inspired by this post (written by madflier) over in the Streamlit discussion forum.

I've previously implemented an authentication and identity solution: Streamlit component for Auth0 Authentication. That's definitely the solution I'd recommend but feel that the Streamlit community has been slow to take it up. Perhaps it's considered to be something for big enterprise applications? Given how easy it is to use Auth0 that's not true. Or perhaps, because Streamlit components can get complicated and require separate Streamlit and web apps to make them work, something else with fewer moving parts is more desirable? I don't know for sure what the blockers are and will be producing some tutorials on Auth0 + Streamlit integration soon to help educate our community.

In the meantime, I think a solution like madflier's will be more palatable for many folks getting started with Streamlit and needing authentication? To fill this gap, I thought I'd build on his application and improve its flexibility and production readiness. Though my aim is contrary to madflier's objectives around simplicity, there are so many requests for simple database-backed authentication in the Streamlit discussion forum that I felt it was worth the effort to take his solution several steps further. As an honorary member of Streamlit's Creators group I recently had the opportunity to work on my idea in a Streamlit-internal hackathon and this is what I'll describe here. Allow me to both apologise to madflier for the many changes I've made to his design and thank him for the initial spark! :-)

What I've built

I've redesigned the original solution and added the following functionality:

  • Session state support so logins survive Streamlit's top-down reruns which occur in it's normal execution.

  • Support for logout, authenticated check, and a requires_auth function decorator to protect areas of your own apps, e.g. secure pages in a multi-page Streamlit application.

    • See how requires_auth is used to secure superuser functions in auth.py. You can do the same in your code.
  • Built-in authentication/login status header widget that will sit nicely in most Streamlit apps.

  • Refactored the SQLite local DB dependency in the main auth module so it uses a DB provider design pattern implementation.

  • Given the refactoring, I added a simple factory for multiple provider implementations, so different persistence technologies could be used, for example a cloud DB.

    • In fact, I built an Airtable cloud database provider which can replace SQLite as an alternative.
  • The abstract provider interface is super simple and should allow almost any database to be adapted, and it works fine for this specific auth use case in the implementations I created.

    • Some Streamliters have mentioned Google Sheets and Firebase - yep, they should be easy.
  • Passwords are stored hashed (MD5) & encrypted (AES256 CBC Extended) in the database, not as plain text. Note, the password is never sent to the browser - it's retrieved, decrypted and matched on the Streamlit server - so is quite secure. I'm definitely following OWASP best practice.

  • Configuration has been externalized for things like database names and locations, cloud service account secrets, api keys, etc. The configuration is managed in a root .env and env.py files, and small Python settings files for the main app (app_settings.py), and each provider implementation (settings.py).

  • There's just enough exception handling to allow you to get a handle on your own extension implementations.

  • I use debugpy for remote debugging support of Streamlit apps, and include a little module that makes it work better with Streamlit's execution reruns.

All code is published under MIT license, so feel free to make changes and please fork the repo if you're making changes and submit pull requests.

If you like this work, consider clicking that star button. Thanks!

Demos

Test application

The Streamlit app app.py illustrates how to hook authlib into your Streamlit applications.

app.py

Database Admin

The Streamlit app admin.py illustrates how to auto-start authlib's superuser mode to create an initial SQLite database and manage users and user credentials.

admin.py

Installation and running the app

To install the pre-requisites, open a console window in the root folder and run:

$ pip install -r requirements.txt

To run the sample application, open a console window in the root folder and run:

# Starts the app on the default port 8765
$ streamlit run app.py

# I use a specific port 8080 like this
$ streamlit run --server.port 8080 app.py

To run the DB Admin application, open a console window in the root folder and run:

$ streamlit run admin.py

Getting started with a SQLite database

There's nothing you need to do as SQLite is part of Python (I use version 3.8.10). The admin.py Streamlit application will handle creating a database and users table for you, and then allow you to populate users, and edit existing databases.

  1. First, assign the STORAGE value in the .env file in the application root folder.

For example:

.env file

# Options are 'SQLITE', 'AIRTABLE'
STORAGE='SQLITE'

A full example (which includes Airtable and encryption key settings) is available in env.sample.

  1. Then, you must run the admin app as shown above to create your initial SQLite database!

Getting started with an Airtable database

How to create an Airtable

  1. First, login into or create a (free) Airtable account.

  2. Next, follow these steps to create an Airtable:

  • Create a database (referred to as a base in Airtable) and a table within the base.
  • You can call the base profile and the table users
  • Rename the primary key default table field (aka column) to username (field type 'Single line text')
  • Add a password field (field type 'Single line text')
  • Add a su (superuser) field (field type 'Number')

Finding your Airtable settings

  1. You can initially create and then manage your API key in the 'Account' overview area
  2. For your base (e.g. profile) go to the 'Help menu' and select 'API documentation'
  3. In 'API documentation' select 'METADATA'
  4. Check 'show API key' in the code examples panel, and you will see something like this:
EXAMPLE USING QUERY PARAMETER
$ curl https://api.airtable.com/v0/appv------X-----c/users?api_key=keyc------X-----i
  • keyc------X-----i is your 'API_KEY' (also in your 'Account' area)
  • appv------X-----c is your 'BASE_ID',
  • users will be your 'TABLE_NAME'

Configuring Airtable's app settings

Assign these values to the keys in the Airtable section of the .env file in the application root folder.

For example:

.env file

# Options are 'SQLITE', 'AIRTABLE'
STORAGE='AIRTABLE'

# Airtable account
AIRTABLE_API_KEY='keyc------X-----i'
AIRTABLE_PROFILE_BASE_ID = 'appv------X-----c'
USERS_TABLE = 'users'

A full example (which includes SQLite and encryption key settings) is available in env.sample.

That's it! You're ready now to use the admin application or Airtable directly to manage the credentials of your users.

TODO

Caveat emptor: You're free to use this solution at your own risk. I have a few features on my wish list:

  • In addition to username, password, and su I want to add additional useful user data to the database: logged_in, expires_at, logins_count, last_login, created_at, updated_at.
  • Provide a Streamlit component wrapper to make it easy to pip install (st_auth maybe??)
  • JavaScript API library making it easy to use the authentication DB in custom component implementations.
  • Would be nice to enhace the library and make an Auth0 provider (leverage my Auth0 component).
  • Deploy the demo app on Streamlit sharing and use it's secrets store instead of my .env solution.
Owner
Arvindra
Arvindra
Complete Two-Factor Authentication for Django providing the easiest integration into most Django projects.

Django Two-Factor Authentication Complete Two-Factor Authentication for Django. Built on top of the one-time password framework django-otp and Django'

Bouke Haarsma 1.3k Jan 04, 2023
Boilerplate/Starter Project for building RESTful APIs using Flask, SQLite, JWT authentication.

auth-phyton Boilerplate/Starter Project for building RESTful APIs using Flask, SQLite, JWT authentication. Setup Step #1 - Install dependencies $ pip

sandhika 0 Aug 03, 2022
A generic, spec-compliant, thorough implementation of the OAuth request-signing logic

OAuthLib - Python Framework for OAuth1 & OAuth2 *A generic, spec-compliant, thorough implementation of the OAuth request-signing logic for Python 3.5+

OAuthlib 2.5k Jan 02, 2023
Graphical Password Authentication System.

Graphical Password Authentication System. This is used to increase the protection/security of a website. Our system is divided into further 4 layers of protection. Each layer is totally different and

Hassan Shahzad 12 Dec 16, 2022
Basic auth for Django.

easy-basicauth WARNING! THIS LIBRARY IS IN PROGRESS! ANYTHING CAN CHANGE AT ANY MOMENT WITHOUT ANY NOTICE! Installation pip install easy-basicauth Usa

bichanna 2 Mar 25, 2022
Foundation Auth Proxy is an abstraction on Foundations' authentication layer and is used to authenticate requests to Atlas's REST API.

foundations-auth-proxy Setup By default the server runs on http://0.0.0.0:5558. This can be changed via the arguments. Arguments: '-H' or '--host': ho

Dessa - Open Source 2 Jul 03, 2020
A flask extension for managing permissions and scopes

Flask-Pundit A simple flask extension to organize resource authorization and scoping. This extension is heavily inspired by the ruby Pundit library. I

Anurag Chaudhury 49 Dec 23, 2022
Django x Elasticsearch Templates

Django x Elasticsearch Requirements Python 3.7 Django = 3 Elasticsearch 7.15 Setup Elasticsearch Install via brew Install brew tap elastic/tap brew

Aji Pratama 0 May 22, 2022
Awesome Django authorization, without the database

rules rules is a tiny but powerful app providing object-level permissions to Django, without requiring a database. At its core, it is a generic framew

1.6k Dec 30, 2022
API with high performance to create a simple blog and Auth using OAuth2 ⛏

DogeAPI API with high performance built with FastAPI & SQLAlchemy, help to improve connection with your Backend Side to create a simple blog and Cruds

Yasser Tahiri 111 Jan 05, 2023
Some scripts to utilise device code authorization for phishing.

OAuth Device Code Authorization Phishing Some scripts to utilise device code authorization for phishing. High level overview as per the instructions a

Daniel Underhay 6 Oct 03, 2022
Two factor authentication system using azure services and python language and its api's

FUTURE READY TALENT VIRTUAL INTERSHIP PROJECT PROJECT NAME - TWO FACTOR AUTHENTICATION SYSTEM Resources used: * Azure functions(python)

BHUSHAN SATISH DESHMUKH 1 Dec 10, 2021
REST implementation of Django authentication system.

djoser REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such

Sunscrapers 2.2k Jan 01, 2023
Simple extension that provides Basic, Digest and Token HTTP authentication for Flask routes

Flask-HTTPAuth Simple extension that provides Basic and Digest HTTP authentication for Flask routes. Installation The easiest way to install this is t

Miguel Grinberg 1.1k Jan 05, 2023
Todo app with authentication system.

todo list web app with authentication system. User can register, login, logout. User can login and create, delete, update task Home Page here you will

Anurag verma 3 Aug 18, 2022
Spotify User Token Generator Template

Spotify User Token Generator Template Quick Start $ pip3 install -r requirements

Arda Soyer 1 Feb 01, 2022
Django-react-firebase-auth - A web app showcasing OAuth2.0 + OpenID Connect using Firebase, Django-Rest-Framework and React

Demo app to show Django Rest Framework working with Firebase for authentication

Teshank Raut 6 Oct 13, 2022
Auth-Starters - Different APIs using Django & Flask & FastAPI to see Authentication Service how its work

Auth-Starters Different APIs using Django & Flask & FastAPI to see Authentication Service how its work, and how to use it. This Repository based on my

Yasser Tahiri 7 Apr 22, 2022
Extending the Django authentication system with a phone verification step.

Extending the Django authentication system with a phone verification step.

Miguel Grinberg 50 Dec 04, 2022
Brute force a JWT token. Script uses multithreading.

JWT BF Brute force a JWT token. Script uses multithreading. Tested on Kali Linux v2021.4 (64-bit). Made for educational purposes. I hope it will help!

Ivan Šincek 5 Dec 02, 2022