the log says that the ‘int’ object has no attribute ‘encode’…
tks @pietroppeter
the log says that the ‘int’ object has no attribute ‘encode’…
tks @pietroppeter
I suspect it may be due to conflicting JWT packages as @pietroppeter mentioned. Please create a new environment and install streamlit-authenticator there and rerun your script.
Hello, very grateful for this addition!
I am having an issue where each refresh is requiring the user to login again. Is this expected or am I missing something?
Thanks!
Hi @William_Sell,
You’re most welcome. Which version of this package are you using? Please try to use >v0.1.5.
Please disregard last message!
This seems to be resolved when I changed expiry_days from 0 → 30.
However, I do still see the login screen flash for a split-second on reload. Not a big deal at all, just FYI ![]()
Hey @William_Sell yes this is unfortunately an issue without any fix yet. As soon as I have found a solution I will release a new version. Cheers.
Have you thought about Oauth login, would love to be able to use one, login with Google, LinkedIn etc.
I’ve just built an easier way to access localStorage from Streamlit (streamlit-ws-localstorage), will try to build a proper oath login soon.
Dear Gabriel,
I have the same issue!! did you solve it?
when I use true username and password nothing happens!
Dear @Sinakian, I suspect this problem is associated with you using an incorrect version of the PyJWT package. Please create a new environment, reinstall streamlit_authenticator, and then try again.
Great idea, sure will look into it for a future release.
Hello everyone
i don’t know why authentication_status is false in initial stage
please let me know
Thank you
Hello, I want to use the Register new user widget. When I register in streamlit app, it did not add new user information in config.yaml file. I dont know why.
how do i use the code:
with open(‘…/config.yaml’, ‘w’) as file:
yaml.dump(config, file, default_flow_style=False)
Hey @gaowudao, I have a hunch that you may be using the wrong library for yaml. Please make sure that you are using PyYAML.
@mkhorasani Hello mkhorasani,thank you for your contribution to this streamlit component. I have a project that is using the official multipage app feature and I would like to protect all pages, by using your streamlit authenticator, I should be able to protect all pages with session state feature, thing is, I only allow my users to have access to my pages for limited amount of time, like 3 days, 30days ,something like that. Each user has an expiration date and time, and users data (including username, password, expiration date and time) is stored on mongodb.com (online database), not on local yaml file.
So, how would i use your streamlit authenticator in my case? if a user has a valid access duration of 3 days, should I just set the cookie expiry to 3 days? but it looks like the cookie settings are pre-set in yaml file? I think when user is trying to login, I should first query the user info from mongodb.com, and check if this user has correct username and password, if both correct, I then need to check if this user account has expired, if expired, reject the user, if this user account is still valid, let’s say , still 2 days and 3 hours left, I need to set the cookie expiry to 2 days and 3 hours. so that after 2 days and 3 hours, the user will be asked to login again , when he tries to login, he will find out his account has expired.
is this the correct process? if not, can you please give me some advice, most importatly, the cookie setting part, how can I set the cookie and cookie expiry time after the user has successfully login to the system (only those with correct username, password and valid ‘subscription’ length will be able to login successfully ), thank you so much!
Dear @streamlit4crypto2022, if you want to manually set/overide the cookie to implement the logic you just mentioned, please follow the below steps:
encoded_cookie = jwt.encode({'name':name_of_user,
'username':username,
'exp_date':expiry_date_as_epox_str},
cookie_key,
algorithm='HS256')
cookie_manager = stx.CookieManager()
cookie_manager.set(cookie_name, encoded_cookie,
expires_at=datetime.now() + timedelta(time_to_expiry))
Please note that the difference between the ‘exp_date’ in the cookie and ‘expires_at’ setting of the cookie are similar yet different. The former will be read and decoded by the application to ensure that the user is authorized to be re-authenticated or not, the latter will be used to automatically remove the cookie from the browser after a certain amount of time. Normally they would both be at the same time.
Hi mkhorasani, huge thanks for the reply, I was out on a business trip for a coupe of days, sorry for the late response.
I am getting this error: (I am using the latest version of streamlit-authenticator 0.2.1)
TypeError: init() got multiple values for argument ‘cookie_expiry_days’
it looks like this authenticator only checks if username and password are correct? if yes, authenticator_status will be set to True?
in my use case, if username and password are both correct, I still need to check subscription expired time by comparing the expired time with current time if subscription does not expire yet, I will authorize the access, if subscription expires, I will not authorize the access and return a message like “subscription expires!”
so how do I define this authenticator below?
do I need to still use the below authenticator and put the same cookie name like “my_streamlit_app” and same “any_random_string_as_key” ,and cookie_expiry_days to be any int
and modify the cookie after detecting authentication_status to be true?
here is my code:
import pickle
from pathlib import Pathimport streamlit as st
import streamlit_authenticator as stauth
import extra_streamlit_components as stx
from datetime import datetime, timedelta
import jwtfile_path = Path(file).parent / “hashed_pw.pkl”
with file_path.open(“rb”) as file:
hashed_passwords = pickle.load(file)authenticator = stauth.Authenticate(names, usernames, hashed_passwords, “my_streamlit_app”, “any_random_string_as_key”, cookie_expiry_days=1)
name, authentication_status, username = authenticator.login(“Login”, “main”)
if authentication_status == False:
st.error(“Username/password is incorrect”)elif authentication_status == None:
st.warning(“Please enter your username and password”)elif authentication_status:
# I can get subscription expired time from online database, but for demo here, I just add 2 minutes to current time. expired_time_from_db = datetime.now() + timedelta(minutes=2) # datetime type # convert subscription expired time to UNIX epoch time epoch_time = str(expired_time_from_db.timestamp()) # string type because you told me that the vaule of 'exp_date' has to be string type # print current local time st.write("current_time: ", datetime.now()) # encoded the cookie info using jwt # the vaule of 'exp_date' has to be UNIX epoch time in string type encoded_cookie = jwt.encode({'name':'Peter', 'username':'peter4streamlit', 'exp_date':epoch_time}, 'any_random_string_as_key', algorithm='HS256') # create a cookie manager instance new_cookie_manager = stx.CookieManager() # create / modify the cookie, it will write the encoded_cookie to the browser # the value of 'expires_at' has to be datetime type new_cookie_manager.set('my_streamlit_app', encoded_cookie, expires_at=expired_time_from_db) # print the cookie expired time, which is the user subscription expired time. st.write("cookie_expired_time: ", expired_time_from_db)
I create user info myself from another streamlit app, I add users manually one by one, I can insert the username, password, and expired_time manually through streamlit app to online database, I think I can hash the password the way you do while adding new users to online datatbase. and for the restricted streamlit app, I can get the username, hashed password and expired time from database when user is trying to login, and pass it to authenticator to verify, that should be no problem for this part.
please any help is appreciated, I can donate you for your contribution. you did a great job for the communication.
You’re most welcome.
Please keep the epoch_time as float:
epoch_time = expired_time_from_db.timestamp()
And also add a random key to the cookie manager as follows:
new_cookie_manager = stx.CookieManager(key='random_cookie_manager_key')
@mkhorasani hello sir, the following does not resolve the issue, I still got the same error even with this
new_cookie_manager = stx.CookieManager(key='random_cookie_manager_key')
I searched the error and according to a post on stackoverflow, it’s due to the new dictionary format in 0.2.1
It looks like the answer by Surajkumar Yadav on the following post solved this “multiple values for argument ‘cookie_expiry_days’” issue.
I still need to add a key for cookie_manager though, and also I need to add another key for the cookie_manager.set(), otherwise, I will get the following error:
DuplicateWidgetID: There are multiple identical st.extra_streamlit_components.CookieManager.cookie_manager widgets with key=‘set’.
Now with my updated code below, I can login without issue, but the original cookie which sets to 1 day is not written to browser, and the step to overwrite/modify of the original cookie is not working either.
I am wondering if I can just set the cookie expiry day to be 0, so that it won’t write the cookie at all. and then after detecting authenticator_status is True , check if expired time obtained from database is longer than current time, if yes, that means the user subscription has not expired yet, thus, allow the user to access the restricted content and write the desired cookie with expired time obtained from database to browser using cookie_manager.set() method. And if the user logs out, the desired cookie will be deleted, I understand that, no problem, what if users login successfully with valid subscription expired time, and leave the page open, do not re-run the page, and the cookie expired time just reached, will the user be automatically log out since the cookie will be deleted after cookie expiry time is hit (is that what you described in previous reply?)
the latter will be used to automatically remove the cookie from the browser after a certain amount of time
I guess although the cookie is removed from browser after a certain amount of time, the user login session is still valid, he won’t be log out automatically right? but if he tries to access any page that requires authenticator_status, he will be log out and asked to login again, is that correct?
another question is , it looks like if I use chrome and press F12, call out the developer tools and switch to applicatons, I can see the cookie and edit the cookie expiry time there??? what is the user knows this method and edit the expiry time, will he gain access for as long as he wants?
sir, I think you should know what i want to do, I have an online database called mongodb, I create user accounts myself, giving them a name, username, password, and expired time for their access to the restricted streamlit app, I can generate random password and hash the password and save the hashed password to the database when creating the user account. this part has no problem at all.
for the streamlit app authenticator, I would like user to be able to login using username, password, when they try to login, I need to get the name, username, hashed password and expired time from online database, and pass it to your authenticator, this part has no problem at all.
thing is , the authenticator currently only checks if username and password are matched, well, no problem I guess I can manually check user account expired time after the authenticator returns True for the authenticator_status, if username and password matches , and also user account has not expired yet, then write the cookie to browser with user account expired time as the cookie expiry time.
I need the user to be automatically logout if the expiry time from cookie is reached, and the cookie should be removed automatically , which you have described previously, cookie can be removed automatically, can user status to be logged out automatically too or not?
can you please try the following code, so you can check the issue that I mentioned?
import streamlit as st
import streamlit_authenticator as stauth
import extra_streamlit_components as stx
import jwt
from datetime import datetime, timedeltast.set_page_config(page_title=“streamlit Dashboard”, page_icon=“
”, layout=“centered”, initial_sidebar_state=“collapsed”, menu_items=None)
hide_st_style = “”"
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
“”"#please use peter4streamlit and pt1234 to login, the hashed passwod is already there.
names = [“Peter”]
usernames = [“peter4streamlit”]
passwords = [“$2b$12$8SS3X25OXTCa4HAtcNjQnO8zODnYcETyJic2UYXPwmxwYTHQPmp8a”] # password: pt1234credentials = {“usernames”:{}}
for uname,name,pwd in zip(usernames,names,passwords):
user_dict = {“name”: name, “password”: pwd}
credentials[“usernames”].update({uname: user_dict})authenticator = stauth.Authenticate(credentials, “my_streamlit_app”, “random_string_key”, cookie_expiry_days=1)
name, authentication_status, username = authenticator.login(“Login”, “main”)
if authentication_status == False:
st.error(“Username/password is incorrect”)
st.markdown(hide_st_style, unsafe_allow_html=True)elif authentication_status == None:
st.warning(“Please enter your username and password”)
st.markdown(hide_st_style, unsafe_allow_html=True)elif authentication_status:
st.markdown(hide_st_style, unsafe_allow_html=True)
#subscription expired time obtain from database, here I use current time + 2 minutes as demo expired time
expired_time_from_db = datetime.utcnow() + timedelta(minutes=2) # datetime typeepoch_time = expired_time_from_db.timestamp() # float type
st.write("current_time: ", datetime.utcnow())
encoded_cookie = jwt.encode({‘name’:‘Peter’,
‘username’:‘peter4streamlit’,
‘exp_date’:epoch_time},
‘random_string_key’, # cookie key #2
algorithm=‘HS256’)new_cookie_manager = stx.CookieManager(key=‘cookie_manager_key’)
new_cookie_manager.set(‘my_streamlit_app’, encoded_cookie, expires_at=expired_time_from_db, key=‘another_cookie_manager_key’)
#print the cookie expired time, which is the user subscription expired time.
st.write("cookie_expired_time: ", expired_time_from_db)
I would like to put {name} and logout button on the same line, but the following method does not work.
col1, col2 = st.columns([1, 1], gap=“small”)
with col1:
st.sidebar.title(f"{name}")with col2:
authenticator.logout(“Logout”, “sidebar”)st.write(“# Welcome to restricted content!..”)
st.subheader(“Introduction :”)
st.text(“1. \n2. \n3. \n4. \n5. \n”)
btw, in this case, there are so many keys and cookie names that I am so confused.
there is cookie name: my_streamlit_app, and cookie key: random_string_key
authenticator = stauth.Authenticate(credentials, “my_streamlit_app”, “random_string_key”, cookie_expiry_days=1)
there is another cooke key: random_string_key, does this key has to be the same key as the previous key above? I am confused, because I am trying to overwrite/modify the original cookie uisng cookie_manager.set(), so do would I define the key here? any requirement?
encoded_cookie = jwt.encode({‘name’:‘Peter’,
‘username’:‘peter4streamlit’,
‘exp_date’:epoch_time},
‘random_string_key’, # cookie key #2
algorithm=‘HS256’)
and here, another key, if I don’t put a key here, an error will raise saying duplicated streamlit widget, suggesting me to use a unique key. any requirement for this key? has nothing to do with the cookie key above?
new_cookie_manager = stx.CookieManager(key=‘cookie_manager_key’)|
finally, I have to add another key for cookie_manager.set(), other streamlit will raise error saying I have to use unique key for widget instead of using ‘set’ for cookie_manager.set, what is the requirement for this key, does it has anything to do with the key from stx.CookieManager ?
new_cookie_manager.set(‘my_streamlit_app’, encoded_cookie, expires_at=expired_time_from_db, key=‘new_cookie_manager_key’)
I know it’s a long post with so many questions, but what i am trying to do is obvious, perhaps a few words from you to clarify or a few lines of code to be added, things will be clear, and problem will be solved. please help resolve this. thank you so much!
I tried, but this error pops up.
‘int’ object has no attribute ‘encode’
and
Nothing happens.
conifg.yaml
credentials:
usernames:
jsmith:
email: jsmith@gmail.com
name: John Smith
password: 123 # To be replaced with hashed password
rbriggs:
email: rbriggs@gmail.com
name: Rebecca Briggs
password: 456 # To be replaced with hashed password
cookie:
expiry_days: 30
key: some_signature_key
name: some_cookie_name
preauthorized:
emails:
code.
import streamlit as st
import streamlit_authenticator as stauth
import yaml
hashed_passwords = stauth.Hasher([‘123’,‘456’]).generate()
with open(‘C:/python/streamlit_1/config.yaml’) as file:
config = yaml.load(file, Loader=yaml.SafeLoader)
authenticator = stauth.Authenticate(
config[‘credentials’],
config[‘cookie’][‘name’],
config[‘cookie’][‘key’],
config[‘cookie’][‘expiry_days’],
config[‘preauthorized’]
)
name, authentication_status, username = authenticator.login(‘Login’, ‘main’)
if authentication_status:
authenticator.logout(‘Logout’, ‘main’)
st.write(f’Welcome {name}')
st.title(‘Some content’)
elif authentication_status == False:
st.error(‘Username/password is incorrect’)
elif authentication_status == None:
st.warning(‘Please enter your username and password’)