User 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. :pray:t2:We’ve been a bit overwhelmed with the amount of questions coming in since launch. :grimacing:

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?

1 Like

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! :heavy_heart_exclamation:

2 Likes

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.

1 Like