Some of you may know I’m into authentication/identity and have implemented a Streamlit component for Auth0 identity integration with Streamlit apps. That’s quite an involved solution and can be intimidating for some. On the other end of the scale is a simple database holding usernames + passwords. @madflier provided a neat solution recently which inspired me to delve into his approach in some detail and apply things I’d learned building enterprise apps to my own version of it. Thanks @madflier!
I recently had the opportunity to work on this idea in a Streamlit-internal hackathon. I’m pleased to share outputs of that effort with the Streamlit community today!
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.
Built-in authentication/login status header widget that will sit nicely in most Streamlit apps.
Support for SQLite DB and Airtable cloud DB providers.
Passwords are stored hashed (MD5) & encrypted (AES256 CBC Extended) in the database, not as plain text.
Configuration has been externalized for things like database names and locations, cloud service account secrets, api keys, etc.
P.S. I’m preparing another implementation and tutorials of my Auth0 identity component (for Auth0), so watch this space.
(.venv) PS D:\streamlit\auth-simple-for-streamlit> streamlit run .\admin.py
2021-08-30 16:13:41.464 >>> Environment loading status <<<
2021-08-30 16:13:41.465 -- Application base directory: D:\streamlit\auth-simple-for-streamlit
2021-08-30 16:13:41.465 -- Dotenv file: D:\streamlit\auth-simple-for-streamlit\.env
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://10.10.0.173:8501
2021-08-30 16:13:41.827 Traceback (most recent call last):
File "d:\streamlit\auth-simple-for-streamlit\.venv\lib\site-packages\streamlit\script_runner.py", line 350, in _run_script
exec(code, module.__dict__)
File "D:\streamlit\auth-simple-for-streamlit\admin.py", line 69, in <module>
import authlib.auth as auth
File "D:\streamlit\auth-simple-for-streamlit\.\authlib\__init__.py", line 3, in <module>
from .common.crypto import aes256cbcExtended
ModuleNotFoundError: No module named 'authlib.common.crypto'
even i pip install authlib , there still got the same error, am i miss something?
and i has installed the requirements
Hi, I’m getting the same error as @lt8cn, but I’m using a Mac and I downloaded the repo after your reply to him–it seems something still isn’t quite right:
Installing collected packages: streamlit, python-dotenv, pycryptodome, pyairtable
Attempting uninstall: streamlit
Found existing installation: streamlit 0.85.1
Uninstalling streamlit-0.85.1:
Successfully uninstalled streamlit-0.85.1
Successfully installed pyairtable-1.0.0rc3 pycryptodome-3.10.1 python-dotenv-0.19.0 streamlit-0.86.0
(py38) qt02537@MacBook-Air ~/local/repos/learn/21Q3/GH/auth-simple-for-streamlit (master) [0|0]
20:07:43$ streamlit run --server.port 8080 app.py
2021-08-30 20:08:20.853 >>> Remote debugging in NOT active <<<
2021-08-30 20:08:20.862 >>> Environment loading status <<<
2021-08-30 20:08:20.862 – Application base directory: /Users/qt02537/local/repos/learn/21Q3/GH/auth-simple-for-streamlit
2021-08-30 20:08:20.862 – Dotenv file:
2021-08-30 20:08:20.871 Traceback (most recent call last):
File “/Users/qt02537/opt/miniconda3/envs/py38/lib/python3.8/site-packages/streamlit/script_runner.py”, line 350, in _run_script
exec(code, module.dict)
File “/Users/qt02537/local/repos/learn/21Q3/GH/auth-simple-for-streamlit/app.py”, line 10, in
from authlib.auth import auth, authenticated, requires_auth
File “/Users/qt02537/local/repos/learn/21Q3/GH/auth-simple-for-streamlit/authlib/init.py”, line 3, in
from .common.crypto import aes256cbcExtended
ModuleNotFoundError: No module named ‘authlib.common.crypto’
You can now view your Streamlit app in your browser.
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://10.10.0.173:8501
2021-08-31 09:48:28.989 Traceback (most recent call last):
File "c:\users\david\appdata\local\programs\python\python39\lib\site-packages\streamlit\script_runner.py", line 349, in _run_script
exec(code, module.__dict__)
File "D:\streamlit\auth-simple-for-streamlit\app.py", line 13, in <module>
user = auth(sidebar=True, show_msgs=True)
File "D:\streamlit\auth-simple-for-streamlit\authlib\auth.py", line 126, in auth
with st.expander('Authentication', expanded=True):
AttributeError: module 'streamlit' has no attribute 'expander'
2021-08-31 09:48:29.446 >>> Remote debugging in NOT active <<<
2021-08-31 09:48:29.446 >>> Environment loading status <<<
2021-08-31 09:48:29.446 -- Application base directory: D:\streamlit\auth-simple-for-streamlit
2021-08-31 09:48:29.446 -- Dotenv file: D:\streamlit\auth-simple-for-streamlit\.env
2021-08-31 09:48:29.455 Traceback (most recent call last):
File "c:\users\david\appdata\local\programs\python\python39\lib\site-packages\streamlit\script_runner.py", line 349, in _run_script
exec(code, module.__dict__)
File "D:\streamlit\auth-simple-for-streamlit\app.py", line 13, in <module>
user = auth(sidebar=True, show_msgs=True)
File "D:\streamlit\auth-simple-for-streamlit\authlib\auth.py", line 126, in auth
with st.expander('Authentication', expanded=True):
AttributeError: module 'streamlit' has no attribute 'expander'
Was auth.db created in ./db when you ran the admin app? (Or, whatever DB name you configured in your .env file.)
The first few console messages at the beginning should be something like this:
_sqlite_provider(allow_db_create=True, if_table_exists=ignore) 2021-08-31 03:07:29.683 >>> Creating table USERS in database auth <<< 2021-08-31 03:07:29.700 Query: SELECT username, password, su FROM USERS 2021-08-31 03:07:50.797 >>> Remote debugging in NOT active <<< 2021-08-31 03:07:50.798 >>> Environment loading status <<< 2021-08-31 03:07:50.800 -- Application base directory: C:\Dev\streamlit\auth-simple-for-streamlit 2021-08-31 03:07:50.802 -- Dotenv file: C:\Dev\streamlit\auth-simple-for-streamlit\.env
Did you then create users in the DB via the admin app?
What version of Streamlit are you using, as the example app.py is reporting AttributeError: module 'streamlit' has no attribute 'expander' – st.expander missing is weird unless you have an old version.
I have also added a minimal auth.db file to GitHub which will help you get started with a DB. Note, the admin and test users have data generated using the default encryption secrets. Once you’re familiar with the workings of the system, change the default encryption secrets and recreate the auth DB from scratch.
(py38) qt02537@MacBook-Air ~/local/repos/learn/21Q3/GH/auth-simple-for-streamlit (master) [0|0]
07:50:33$ streamlit run admin.py
2021-08-31 07:51:28.900 >>> Remote debugging in NOT active <<<
2021-08-31 07:51:28.903 >>> Environment loading status <<<
2021-08-31 07:51:28.904 -- Application base directory: /Users/qt02537/local/repos/learn/21Q3/GH/auth-simple-for-streamlit
2021-08-31 07:51:28.904 -- Dotenv file:
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://10.3.18.7:8501
2021-08-31 07:51:37.229 >>> Remote debugging in NOT active <<<
2021-08-31 07:51:37.230 >>> Environment loading status <<<
2021-08-31 07:51:37.230 -- Application base directory: /Users/qt02537/local/repos/learn/21Q3/GH/auth-simple-for-streamlit
2021-08-31 07:51:37.230 -- Dotenv file:
_sqlite_provider(allow_db_create=True, if_table_exists=ignore)
note that a database was created:
(py38) qt02537@MacBook-Air ~/local/repos/learn/21Q3/GH/auth-simple-for-streamlit (master) [0|0]
07:54:08$ ll db
total 24
drwxr-xr-x 4 qt02537 staff 128 Aug 31 07:36 .
drwxr-xr-x 20 qt02537 staff 640 Aug 30 20:08 ..
-rw-r--r-- 1 qt02537 staff 12288 Aug 31 07:36 auth.db
-rw-r--r-- 1 qt02537 staff 0 Aug 30 20:05 fake_for_github_repo.txt
i already test the prj , clone from github and make a .env file in the prj dir,than all error will be fixed. mac or linux cp env.sample .env windows copy env.sample .env
thank you so much for share the awesome prj !
I just wanted to say that this was incredibly helpful for me.
I’ve got it successfully working locally for my project (& paired it with st.secrets to keep my database token hidden).
I had a question though. I’ve never deployed a streamlit app before but would you have any tips for the best way to do so with this solution? Are there any pitfalls with, say, heroku? Would I leave the admin.py off the server, for example?
@rahul-psych
That’s great to hear and encouragement to do more. Thanks.
Taking the .env file approach vs. st.secrets and secrets.toml is a matter of taste. Definitely would prefer the latter for deployments to Streamlit Sharing. Regarding deployments to Heroku, assuming the server is secure, I see no problem in leaving admin.py there. But note you’d have to run it from the Heroku management console in headless mode, on a different port than the main app. The passwords are encrypted and as long as you have a strong password for the admin super user, you can safely manage the database from the main app. If you don’t want that management feature exposed in the main app, then comment out the code in auth.py that invokes super user mode when a SU logs in. It’s a lot easier to use Airtable because you can connect to it by running admin.py locally, avoiding having to run it in headless mode in Heroku, each time you want to edit the user DB. Airtable is free for 1000 records, so should be sufficient for most scenarios.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.