New Component: streamlit-oauth

Hey @dnplus, thanks for merging my PR. When are you planning to release new version? I would be happy to start using new changes.

Hey there!

I have uploaded a new package for you to check out. Additionally, I wanted to give you a heads up that I am considering adding some enhancements to the package next month.

Thank you for your continued support and let me know if you have any questions or feedback.

Thanks.

Dylan Lu
在 2023年8月29日 +0800 PM2:28,Michał via Streamlit notifications@streamlit.discoursemail.com,写道:

Thanks @dnplus . Appreciate it :slight_smile:

Hey @dnplus, I’ve just checked out 0.0.2 and looks like it’s missing frontend directory. That’s why it will be impossible to use it. Is there a chance to fix it?

I have uploaded a new version, I forgot to build the frontend source first. My apologies.
在 2023年8月30日 +0800 PM1:45,Michał via Streamlit notifications@streamlit.discoursemail.com,写道:

Thanks a lot @dnplus

Use this library to use google auth in your Streamlit application

import streamlit as st
from google_auth import Google_auth

client_id = “hasjh5jk498ufiu3h89g8-aghdszjhk3k.apps.googleusercontent.com
client_secret = “afsghfbkhfdjdsgfdjhfjkfhjkfhkjhkjdhks”

login = Google_auth(clientId=client_id, clientSecret=client_secret)

if login == “authenticated”:
# your streamlit applciation
pass

else:
st.warning(“login failed”)

hello, @dnplus, hope you’re doing well.
I am trying to set up a “Google Authentification” to a streamlit app, and i found your component here blog post. i have some questions if it’s possible:
Fisrt, here is the code i am using :

import streamlit as st
from streamlit_oauth import OAuth2Component

# Set environment variables
AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth"
TOKEN_URL = "https://oauth2.googleapis.com/token"
REFRESH_TOKEN_URL = "https://oauth2.googleapis.com/token"
REVOKE_TOKEN_URL = "https://oauth2.googleapis.com/revoke"
CLIENT_ID = "CLIENT_ID "
CLIENT_SECRET = "CLIENT_SECRET "
REDIRECT_URI = "http://localhost:8501"
SCOPE = "openid profile email"

oauth2 = OAuth2Component(CLIENT_ID, CLIENT_SECRET, AUTHORIZE_URL, TOKEN_URL, REFRESH_TOKEN_URL, REVOKE_TOKEN_URL)

# Check if token exists in session state
if 'token' not in st.session_state:
    # If not, show authorize button
    result = oauth2.authorize_button("Authorize", REDIRECT_URI, SCOPE)
    if result and 'token' in result:
        # If authorization successful, save token in session state
        st.session_state.token = result.get('token')
        # THE MAIN APP if user authenticate
        st.title("App On")
        
  else:
    token = st.session_state['token']
      

as you can see, the purpose is to give access to the app only for the users that authenticate :

  1. am i doing some code logic mistakes ?
  2. after a user authenticate, how can i keep his session “open” even if he refrsesh the app
  3. can i have a list of the e-mail that authenticate
  4. is it possible the change the “Authorize” to a “google logo”

Thank you !

use this

import streamlit as st
from StreamlitGauth.google_auth import Google_auth

client_id = “”
client_secret = “”
redirect_uri = “http://localhost:8501

login = Google_auth(
clientId=client_id, clientSecret=client_secret, redirect_uri=redirect_uri
)

if login == “authenticated”:
st.success(“hello”)
pass

1 Like
  1. seems to work, you need to add an extra param type=offline to get a refresh token when using Google
  2. you can store the token in the database and use cookies to maintain the use session
  3. you will receive a id_token, it contains the user email
  4. currently not supported
1 Like

hello @Rahul_Katoch1, thank you for this amazing library.

Please how can ia get emails that authenticate ?
And is there a way to hide the Google “button” after login ?
i have tried this code, but it doeasn’t work :

import streamlit as st
from StreamlitGauth.google_auth import Google_auth

client_id = ""
client_secret = ""
redirect_uri =  ""
a = st.empty()
with a.container():
    login = Google_auth(
    clientId=client_id, clientSecret=client_secret, redirect_uri=redirect_uri)

if login == "authenticated":
    a.empty()
    st.title("Streamlit Oauth Login")

else:
    st.warning("login failed")

For mail confirmation, you can use SMTP. After logging in, you can change your redirect URL or open it in a new window. If you don’t want to do that, I’ll fix the issue so that after logging in, the Google button is made sure to be hidden.

2 Likes

Hi

You can specify the icon in the new version 0.1.0 now

icon can be data:image or image URL

result = oauth2.authorize_button("Continue with Google", REDIRECT_URI, SCOPE, icon="data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 48 48'%3E%3Cdefs%3E%3Cpath id='a' d='M44.5 20H24v8.5h11.8C34.7 33.9 30.1 37 24 37c-7.2 0-13-5.8-13-13s5.8-13 13-13c3.1 0 5.9 1.1 8.1 2.9l6.4-6.4C34.6 4.1 29.6 2 24 2 11.8 2 2 11.8 2 24s9.8 22 22 22c11 0 21-8 21-22 0-1.3-.2-2.7-.5-4z'/%3E%3C/defs%3E%3CclipPath id='b'%3E%3Cuse xlink:href='%23a' overflow='visible'/%3E%3C/clipPath%3E%3Cpath clip-path='url(%23b)' fill='%23FBBC05' d='M0 37V11l17 13z'/%3E%3Cpath clip-path='url(%23b)' fill='%23EA4335' d='M0 11l17 13 7-6.1L48 14V0H0z'/%3E%3Cpath clip-path='url(%23b)' fill='%2334A853' d='M0 37l30-23 7.9 1L48 0v48H0z'/%3E%3Cpath clip-path='url(%23b)' fill='%234285F4' d='M48 48L17 24l-4-3 35-10z'/%3E%3C/svg%3E", use_container_width=True)

preview like this

1 Like

“For mail confirmation, you can use SMTP”

Could you please elaborate on this?
How do I read the email address of the logged in user?

Thanks for the library BTW.

Hello @dnplus, happy to see your reply !
Could you give an example about the steps 1, 2 and 3 ?

Ad thank you for the image “Continue with Google” it gives a better UX.

Hi @Snow_Yoo, for step 2 you can try creating a session cookie to manage the session.

I have tried extra_streamlit_components cookie manager but it seems it conflicts with my package flow, it will cause the authorize_button trigger multiple times.

for steps 1, 3 example

import streamlit as st
from streamlit_oauth import OAuth2Component
from httpx_oauth.clients.google import GoogleOAuth2
import os
import base64
import json

# import logging
# logging.basicConfig(level=logging.INFO)

st.title("Google OIDC Example")
st.write("This example shows how to use the OAuth2 component to authenticate with a Google OAuth2.")

# create an OAuth2Component instance
CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID")
CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET")

if "auth" not in st.session_state:
    # create a button to start the OAuth2 flow
    client = GoogleOAuth2(CLIENT_ID, CLIENT_SECRET)
    oauth2 = OAuth2Component(None, None, None, None, None, None, client=client)
    result = oauth2.authorize_button(
        name="Continue with Google",
        icon="https://www.google.com.tw/favicon.ico",
        redirect_uri="http://localhost:8501",
        scope="openid email profile",
        key="google",
        use_container_width=True,
    )

    if result:
        st.write(result)
        # decode the id_token jwt and get the user's email address
        id_token = result["token"]["id_token"]
        # verify the signature is an optional step for security
        payload = id_token.split(".")[1]
        # add padding to the payload if needed
        payload += "=" * (-len(payload) % 4)
        payload = json.loads(base64.b64decode(payload))
        email = payload["email"]
        st.session_state["auth"] = email
        st.rerun()
else:
    st.write("You are logged in!")
    st.write(st.session_state["auth"])
    st.button("Logout")
    del st.session_state["auth"]

I plan to add some examples in my GitHub source

2 Likes

Hi @dnplus,

Using your example code I was able to perform google authentication. However, reloading or refreshing the page, the user needs to re-login.

Is there a way to handle this so that the user experience is similar to what we see normally?

Thanks.

Hi @nikhil_no_1
You have to persist user session by using cookie/local storage by 3rd-party library, streamlit handle the session within websocket connection, if user refresh the page websocket will reconnect.

I am considering to built-in the session control in next version.

3 Likes

Thank You. Will wait for it :+1:

Thank you for the great library, @dnplus!

Question: how would this work with a multipage app? Would we have to save the session using cookie/local storage and then have the same auth flow on every page of the app?