Hey guys, I am trying to build a login wall with Google OAuth.
When logging the user for the first time I store the OAuth token in st.session_state.token.
However, every time I refresh the page, the session_state gets erased and throws the client out of the page.
There is also a problem with write_access_token() function in the code because it always returns an “malformed auth code” error.
But still, even if it worked it would refresh the session_state anyway.
Is there a way to set an expiration time for session_state? How do you keep your users logged in after they refresh the page?
Did you resolved you issue? I got same problem with you, I’m building a simple login page now, my example is very simple, just require user to input a password (no username), then I stored this password in session, if user visit next time or the page get refreshed, I will get that password from session to verify the request, but each time the page refreshed, the session dicta is empty.
Thanks! but still not working, here is my code, if I refresh the page, it always print a empty dict:
import streamlit as st
print(st.session_state)
if 'password' in st.session_state:
st.success('Good')
else:
password = st.text_input('Password')
confirm = st.checkbox('Confirm')
if confirm:
if password == '123':
st.session_state.password = password
st.success('Good')
else:
st.warning('Try again!')
What I want is, unless user closed his browser otherwise user will no need to input the password again.
The session is tied to the socket connection so when you refresh the browser the socket is killed and renewed. You’d could use a database to store your token, or try wrapping your token state update and retrieval in st.experimental_memo with disk persistence.
I’ve seen a cookies implementation in the forum, that may also help to persist the token.
I’ve published a couple of login solutions too that may help (one simple using a database and another more about identities using Auth0). Just see my posts.
So, what I ended up doing is setting a param in the url everytime the user logs in and only deleting it when he logs out. Url params remain the same on page refresh.
Login: st.experimental_set_query_params(code=“logged_in”) everytime the user logs in. Check Login: st.experimental_get_query_params()[‘code’][0] Logout: st.experimental_set_query_params(code=“logged_out”)
Here is my code.
main.py
def main(user: object):
st.write(f"You're logged in as {st.session_state['user']['email']}")
set_code(code=user['refreshToken'])
st.write("Hello World")
app.py
if __name__ == '__main__':
# firebase configuration
firebaseConfig = {
"apiKey": os.environ['APIKEY'],
"authDomain": os.environ['AUTHDOMAIN'],
"databaseURL": os.environ['DATABASEURL'],
"projectId": os.environ['PROJECTID'],
"storageBucket": os.environ['STORAGEBUCKET'],
}
firebase = pyrebase.initialize_app(firebaseConfig)
auth = firebase.auth()
# authentification
if "user" not in st.session_state:
st.session_state['user'] = None
if st.session_state['user'] is None:
try:
code = st.experimental_get_query_params()['code'][0]
refreshToken = refresh_session_token(auth=auth, code=code)
if refreshToken == 'fail to refresh':
raise(ValueError)
user = get_user_token(auth, refreshToken=refreshToken)
main(user=user)
except:
st.title("Login")
login_form(auth)
else:
main(user=st.session_state['user'])
auth.py
import streamlit as st
import requests
def set_code(code: str):
st.experimental_set_query_params(code=code)
def login_form(auth):
email = st.text_input(
label="email", placeholder="fullname@gmail.com")
password = st.text_input(
label="password", placeholder="password", type="password")
if st.button("login"):
try:
user = auth.sign_in_with_email_and_password(email, password)
st.session_state['user'] = user
st.experimental_rerun()
except requests.HTTPError as exception:
st.write(exception)
def logout():
del st.session_state['user']
st.experimental_set_query_params(code="/logout")
def get_user_token(auth, refreshToken: object):
user = auth.get_account_info(refreshToken['idToken'])
user = {
"email": user['users'][0]['email'],
"refreshToken": refreshToken['refreshToken'],
"idToken": refreshToken['idToken']
}
st.session_state['user'] = user
return user
def refresh_session_token(auth, code: str):
try:
return auth.refresh(code)
except:
return "fail to refresh"
Great you got it working… highlights that session state is nice, but certainly not resilient and there are cases where it just can’t be used (as expected with a pure web app session state… Web app sessions (cookies, more specifically) and Streamlit app sessions are not equal).
@danielhangan Does this mean if the user shares the URL to the streamlit app with someone and accidentally copies the query parameters, the new user will be able to log in on their behalf?
Gotchu. Thanks! I was able achieve something similar but I used cookies instead of query-parameter to be session-safe. Quick question: do you know if there’s something wrong with moving the main() function to the if __name__ == '__main__': block or should you always have it outside?
In my case, I get and AWS credentials through argparse and create two st.session_state in the home.py, expecting to use them in other pages. Unfortunatelly I get the same problems mentioned previously. My suggestion would be to re-launch streamlit the same way it was launched initially (with the same arguments used in the original execution. Would that make the session_state vars be correctly initialized and reusable across all pages?
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.