diff --git a/README.md b/README.md index 2eade63f..a44d411f 100644 --- a/README.md +++ b/README.md @@ -20,27 +20,43 @@ import streamlit_authenticator as stauth ### 1. Hashing Passwords -* Initially define your users' names, usernames, and plain text passwords. +* Initially define your users' names, usernames, plain text passwords, and reauthentication cookie settings in a YAML configuration file. ```python -names = ['John Smith', 'Rebecca Briggs'] -usernames = ['jsmith', 'rbriggs'] -passwords = ['123', '456'] +credentials: + names: ['John Smith', 'Rebecca Briggs'] + usernames: ['jsmith', 'rbriggs'] + passwords: ['123', '456'] # To be replaced with hashed passwords +cookie: + name: 'some_cookie_name' + key: 'some_signature_key' + expiry_days: 30 ``` -* Then use the hasher module to convert the plain text passwords to hashed passwords, and remove all plain text passwords from your source code. +* Then use the Hasher module to convert the plain text passwords to hashed passwords. ```python -hashed_passwords = stauth.Hasher(passwords).generate() +hashed_passwords = stauth.Hasher(['123', '456']).generate() ``` +Finally replace the plain text passwords in the configuration file with the hashed passwords. + ### 2. Creating Login Widget -* Subsequently use the hashed passwords to create an authentication object. Here you will need to enter a name for the JWT cookie that will be stored on the client's browser and used to reauthenticate the user without re-entering their credentials. In addition, you will need to provide any random key to be used to hash the cookie's signature. Finally, you will need to specify the number of days to use the cookie for, if you do not require passwordless reauthentication, you may set this to 0. +* Subsequently import the configuration file into your script to create an authentication object. Here you will need to enter a name for the JWT cookie that will be stored on the client's browser and used to reauthenticate the user without re-entering their credentials. In addition, you will need to provide any random key to be used to hash the cookie's signature. Finally, you will need to specify the number of days to use the cookie for, if you do not require passwordless reauthentication, you may set this to 0. ```python -authenticator = stauth.Authenticate(names, usernames, hashed_passwords, - 'some_cookie_name', 'some_signature_key', cookie_expiry_days=30) +with open('../config.yaml') as file: + config = yaml.load(file, Loader=SafeLoader) + +authenticator = stauth.Authenticate( + config['credentials']['names'], + config['credentials']['usernames'], + config['credentials']['passwords'], + config['cookie']['name'], + config['cookie']['key'], + config['cookie']['expiry_days'] +) ``` * Then finally render the login module as follows. Here you will need to provide a name for the login form, and specify where the form should be located i.e. main body or sidebar (will default to main body). @@ -57,7 +73,7 @@ name, authentication_status, username = authenticator.login('Login', 'main') ```python if authentication_status: authenticator.logout('Logout', 'main') - st.write('Welcome *%s*' % (name)) + st.write(f'Welcome *{name}*') st.title('Some content') elif authentication_status == False: st.error('Username/password is incorrect') @@ -70,7 +86,7 @@ elif authentication_status == None: ```python if st.session_state['authentication_status']: authenticator.logout('Logout', 'main') - st.write('Welcome *%s*' % (st.session_state['name'])) + st.write(f'Welcome *{st.session_state["name"]}*') st.title('Some content') elif st.session_state['authentication_status'] == False: st.error('Username/password is incorrect') diff --git a/config.yaml b/config.yaml index 08c175de..8ec85f03 100644 --- a/config.yaml +++ b/config.yaml @@ -1,7 +1,9 @@ -cookie: - name: 'some_cookie_name' - key: 'some_signature_key' credentials: names: ['John Smith', 'Rebecca Briggs'] usernames: ['jsmith', 'rbriggs'] - passwords: ['123', '456'] + passwords: ['$2b$12$RITgFvOneaLd7DvPS6UhZeRpZDPjnGvTKV.FCMNWRM92fz7ZapuC2', + '$2b$12$to1ADtwtCOFGMFNow7iJj.GjWWqy6FOEeeBjl/c.FmCZBSkf2bCr.'] +cookie: + name: 'some_cookie_name' + key: 'some_signature_key' + expiry_days: 30 diff --git a/setup.py b/setup.py index 062d6ed9..f6e02707 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="streamlit-authenticator", - version="0.1.4", + version="0.1.5", author="Mohammad Khorasani", author_email="khorasani.mohammad@gmail.com", description="A secure authentication module to validate user credentials in a Streamlit application.", diff --git a/streamlit_authenticator/__init__.py b/streamlit_authenticator/__init__.py index ef92b341..da57ed97 100644 --- a/streamlit_authenticator/__init__.py +++ b/streamlit_authenticator/__init__.py @@ -160,9 +160,10 @@ def login(self, form_name, location='main'): if self.token is not False: if not st.session_state['logout']: if self.token['exp_date'] > datetime.utcnow().timestamp(): - st.session_state['name'] = self.token['name'] - st.session_state['authentication_status'] = True - st.session_state['username'] = self.token['username'] + if 'name' and 'username' in self.token: + st.session_state['name'] = self.token['name'] + st.session_state['username'] = self.token['username'] + st.session_state['authentication_status'] = True if st.session_state['authentication_status'] != True: if location == 'main': @@ -226,25 +227,26 @@ def logout(self, button_name, location='main'): st.session_state['authentication_status'] = None if not _RELEASE: + + #hashed_passwords = Hasher(['123', '456']).generate() + with open('../config.yaml') as file: config = yaml.load(file, Loader=SafeLoader) - hashed_passwords = Hasher(config['credentials']['passwords']).generate() - authenticator = Authenticate( config['credentials']['names'], config['credentials']['usernames'], - hashed_passwords, + config['credentials']['passwords'], config['cookie']['name'], config['cookie']['key'], - cookie_expiry_days=30 + config['cookie']['expiry_days'] ) name, authentication_status, username = authenticator.login('Login', 'main') if authentication_status: authenticator.logout('Logout', 'main') - st.write('Welcome *%s*' % (name)) + st.write(f'Welcome *{name}*') st.title('Some content') elif authentication_status == False: st.error('Username/password is incorrect') @@ -255,12 +257,11 @@ def logout(self, button_name, location='main'): # st.session_state['authentication_status'] to access the name and # authentication_status. - #authenticator.login('Login', 'main') - - #if st.session_state['authentication_status']: - # st.write('Welcome *%s*' % (st.session_state['name'])) - # st.title('Some content') - #elif st.session_state['authentication_status'] == False: - # st.error('Username/password is incorrect') - #elif st.session_state['authentication_status'] == None: - # st.warning('Please enter your username and password') + # if st.session_state['authentication_status']: + # authenticator.logout('Logout', 'main') + # st.write(f'Welcome *{st.session_state["name"]}*') + # st.title('Some content') + # elif st.session_state['authentication_status'] == False: + # st.error('Username/password is incorrect') + # elif st.session_state['authentication_status'] == None: + # st.warning('Please enter your username and password')