Is it possible to add an authentication step to access streamlit?
I want to control so that only users who can provide a correct username/password can access the content.
Example: https://dash.plot.ly/authentication
Is it possible to add an authentication step to access streamlit?
I want to control so that only users who can provide a correct username/password can access the content.
Example: https://dash.plot.ly/authentication
Welcome to the community, @fogel!
Unfortunately I donât have a good solution for you right now. We are working on this as part of the Streamlit for Teams offering which is in limited beta right now and will be rolling out in early 2020.
If you donât need true authentication, you could just set up a passphrase using st.text_input and only show the app if the answer matches the passphrase you set. Itâs not ideal, but if you are just trying to gate access that would work. A related feature request weâre tracking will also enable password text_inputs.
Thank you for using Streamlit and we apologize for the delay. Weâve been a bit overwhelmed with the amount of questions coming in since launch.
I have a very hacky but 9000% secure solution for you =)
Deploy an app to a server
Close all ports except 22 (ssh)
Launch streamlit on some port locally
Do not expose this port to the world
Use ssh tunnel to access your streamlit app
Whenever you grant access to someone just add his public ssh key to authorized_keys
(we do it all the time with notebooks and similar things)
Is it possible if we make iframe to streamlit? so, the authenticated user will be redirected to this iframe page?
Unfortunately, you really canât; modern browsers will not allow insecure http-based content via https.
Even if you could, it wouldnât really be secure. The streamlit app contained within the iframe would still be open to the world and exploitable by anybody scanning for open ports.
One way to do this would be to set up the streamlit app behind a web server reverse proxy, using https (Apache2 or Nginx). Hereâs a good stackoverflow conversation about how to make this work on Nginx (in the example, imagine that your streamlit app is running on port 3001). Then you would need to apply HTTPS settings to those server definitions as in the Nginx https documentation here.
Then you would load the iframe with the basic Auth params supplied in the URL through your user-authenticated web page. Itâs not a perfect solution, but at least you can guarantee that the credentials will only be embedded in pages meant for logged-in users. Youâll have to trust your users not to reshare the link.
I know this seems convoluted; right now Streamlit has been optimized as an internal tool for sharing data science and ML results. We can see that people really want to use it as a web app deployment tool, and our engineering path is being influenced by that!
Hello Amanda,
We tried your proposed solution with text_input, however now it is always displaying password, is there a way to hide this text input widget after âsuccessfull matchâ or text provided in it?
Hey @Galkinpro ,
You could solve that using an empty() element, for instance:
import streamlit as st
def is_authenticated(password):
return password == "admin"
def generate_login_block():
block1 = st.empty()
block2 = st.empty()
return block1, block2
def clean_blocks(blocks):
for block in blocks:
block.empty()
def login(blocks):
blocks[0].markdown("""
<style>
input {
-webkit-text-security: disc;
}
</style>
""", unsafe_allow_html=True)
return blocks[1].text_input('Password')
def main():
st.header('Hello')
st.balloons()
login_blocks = generate_login_block()
password = login(login_blocks)
if is_authenticated(password):
clean_blocks(login_blocks)
main()
elif password:
st.info("Please enter a valid password")
Take in account that the password appearance style will only work in Chromium based browsers.
Here is my very simple workaround:
password = st.sidebar.text_input("Password:", value="")
# select our text input field and make it into a password input
js = "el = document.querySelectorAll('.sidebar-content input')[0]; el.type = 'password';"
# passing js code to the onerror handler of an img tag with no src
# triggers an error and allows automatically running our code
html = f'<img src onerror="{js}">'
# in contrast to st.write, this seems to allow passing javascript
div = Div(text=html)
st.bokeh_chart(div)
if password != os.environ["PASSWORD"]:
st.error("the password you entered is incorrect")
return
what import enabled you to use this function
Hi @John_M
I guess this is a bokeh object, so probably from bokeh.models import Div
.
exactly, thanks. unfortunately, it seems i canât edit my previous post anymore, but thanks for clearing that up.
The workaround isnât needed anymore, however, as newer versions of streamlit do support a password field: st.text_input("Password:", value="", type="password")
You can also put auth in front of the application rather than inside it. For example, using oauth for login with nginx https://github.com/cloudflare/nginx-google-oauth/blob/master/README.md#docker-image
In case this helps anyone - this was super helpful: https://github.com/Taxuspt/heroku_streamlit_nginx
I have this below code to do the minmal user authentication. This is based on the SessionState hack here. Is there a better approach to achieve the below functionality
from SessionState import get
session_state = get(password='')
if session_state.password != 'pwd123':
pwd_placeholder = st.sidebar.empty()
pwd = pwd_placeholder.text_input("Password:", value="", type="password")
session_state.password = pwd
if session_state.password == 'pwd123':
pwd_placeholder.empty()
main()
else:
st.error("the password you entered is incorrect")
else:
main()
The approach above by @nth-attempt worked quite well for me, thanks!
Minor suggestion: instead of
else:
st.error("the password you entered is incorrect")
I would do elif session_state.password != ''
, so that the error doesnât show up when the password is blank!
thanks for sharing, this works well
I did a simple test and oauth2-proxy seems to be a interesting option!
Itâs a simple oauth proxy, therefore I could protect my streamlit application behind a google-login page.
Please be aware that oauth is not a trivial flow so, consider wisely all your requirements (i.e. logout, security, etc)
Simple demo:
Hi and thx for the suggestions!
I have the following error:
ModuleNotFoundError: No module named 'SessionState'
I tried to install various libraries but the error is still there.
Any idea anyone?
Thanks,
Charly
Hi Charly,
You need the SessionState gist. I.e. put the file SessionState.py from here in your project.
There are are different versions of the SessionState gist out there, but it looks like this one is recent. See e.g. this thread for some additional inspiration.
Best regards,
Peter
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.
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.
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.
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.