New Component: 🔐 Google authentification and Sign In with Google button

Hello Streamlit community! :wave:

I recently created a small PyPI package called streamlit-google-auth.

This package provides a simple and easy-to-use integration of Google authentication in your Streamlit application.

Getting Started

  1. Install the package:
    pip install streamlit-google-auth
  2. Create a Google Cloud Platform project and obtain the client ID and client secret. You can follow the instructions here to create the credentials.
  3. Save the client ID and client secret in a JSON file (e.g., google_credentials.json).
  4. Import the necessary modules and initialize the Authenticate class:
import streamlit as st
from streamlit_google_auth import Authenticate

authenticator = Authenticate(
    secret_credentials_path='google_credentials.json',
    cookie_name='my_cookie_name',
    cookie_key='this_is_secret',
    redirect_uri='http://localhost:8501',
)
  1. Check if the user is already authenticated and handle the login/logout flow:
# Check if the user is already authenticated
authenticator.check_authentification()

# Display the login button if the user is not authenticated
authenticator.login()

# Display the user information and logout button if the user is authenticated
if not st.session_state['connected']:
    st.image(st.session_state['user_info'].get('picture'))
    st.write(f"Hello, {st.session_state['user_info'].get('name')}")
    st.write(f"Your email is {st.session_state['user_info'].get('email')}")
    if st.button('Log out'):
        authenticator.logout()

That’s it! Your Streamlit app now has Google authentication integrated.

Configuration

The Authenticate class takes the following parameters:

  • secret_credentials_path: The path to the Google Cloud Platform credentials JSON file.
  • cookie_name: The name of the cookie used to store the authentication information.
  • cookie_key: The secret key used to encrypt the cookie.
  • redirect_uri: The redirect URI of your Streamlit application.
  • cookie_expiry_days: Optional, The number of days the cookie stay valid.

Functions

The Authenticate class provides the following functions:

  • check_authentification(): Catch the event when the user come back from the google login page and log it.
  • login(): Displays the login button and handles the authentication flow.
  • logout(): Logs out the user and clears the session state.
  • get_authorization_url(): Returns the URL for the Google authentication page.

Session State

The Authenticate class updates the following keys in the Streamlit session state:

  • connected: A boolean indicating whether the user is authenticated or not.
  • oauth_id: The unique identifier for the authenticated user.
  • user_info: A dictionary containing the user’s name, email, and profile picture URL.

Example

Here’s a complete example of how to use the Authenticate class in a Streamlit app:

import streamlit as st
from streamlit_google_auth import Authenticate

st.title('Streamlit Google Auth Example')

authenticator = Authenticate(
    secret_credentials_path = 'google_credentials.json',
    cookie_name='my_cookie_name',
    cookie_key='this_is_secret',
    redirect_uri = 'http://localhost:8501',
)

# Catch the login event
authenticator.check_authentification()

# Create the login button
authenticator.login()

if st.session_state['connected']:
    st.image(st.session_state['user_info'].get('picture'))
    st.write('Hello, '+ st.session_state['user_info'].get('name'))
    st.write('Your email is '+ st.session_state['user_info'].get('email'))
    if st.button('Log out'):
        authenticator.logout()

Check the Github for more infos and maybe leave a star :star:: HERE
Or the PyPI page: PyPI link

5 Likes

This is super handy! Thanks for creating this @Adrien_Bouvais! :raised_hands:

Thanks @Adrien_Bouvais. This is helpful.

In your app, which method are you using? #3 or #4?
I need the same functionality that you have currently in the app.

Hi @Adrien_Bouvais ,

Both the methods are not working for me. After login it redirects back to the same login page.

My javascript origin and redirect uri are set to same URL.

1 Like

Hello, this should be solve now.
Please ask on github regarding bugs and issues.

Hi! I have your component sort of working right now but the connected session is always set to False. I set up a local domain (mylocaldomain.com) and set that to my local website - 10.1.10.25:8501. I can click the Google login button, go through the authentication, and then I am returned to my site via the Hosts file. That said, the connected session state is still False.

I really appreciate all of the work you have done and I hate to bug you but do you have any ideas why this is failing?

authenticator = Authenticate(
secret_credentials_path=‘./credentials.json’,
cookie_name=‘My-Local-Cookie’,
cookie_key=‘aDdfnds99DJdjs’,
redirect_uri=http://mylocaldomain.com:8501,
)
authenticator.login()

if “connected” in st.session_state and not st.session_state[‘connected’]:
logging.debug(f"Connected is: {st.session_state[‘connected’]}")

I finally figured this out, you have this statement:

authorization_url, state = flow.authorization_url(
access_type=“offline”,
include_granted_scopes=“true”,
)

The include_granted_scopes=“true” returns ALL the scopes in a given app which, if it does not match the request, causes issues. If you drop that one line then everything works without issue.

Thank you for the control!

Hi Folks!
I’m trying to setup google authentication to a published app, but reached a roadblock. Although it does work on local domain (http://localhost:8501) it raises a “connection with localhost was refused”

The funny thing is that I can connect from my PC both through local host and web, but if I try on my phone then I get the error above.

I suspect it is something related to the fact I have two redirect URIs on mu credentials dict, which I guess is the correct way since I want to be able to have google authentication from both environments, but I’m not sure.

    "web": {
        "client_id": os.environ["GOOGLE_CLIENT_ID"],
        "project_id": os.environ["GOOGLE_PROJECT_ID"],
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_secret": os.environ["GOOGLE_CLIENT_SECRET"],
        "redirect_uris": [
            'https://bargain-bungalow.streamlit.app',
            'http://localhost:8501'
        ],
        "javascript_origins": [
            'https://bargain-bungalow.streamlit.app',
            'http://localhost:8501'
        ],
    }
}

Also, to initiallize the the Authenticate object, I change the redirect_uri depending on where the app is running

def create_redirect_uri() -> str:
    if is_running_locally():
        redirect_uri = "http://localhost:8501"
    else:
        redirect_uri = "https://bargain-bungalow.streamlit.app"
    return redirect_uri
def get_authenticator():
    redirect_uri = create_redirect_uri()
    create_google_credentials_file(redirect_uri)
    authenticator = Authenticate(
        secret_credentials_path="google_credentials.json",
        cookie_name="bargain_bungalow_cookie_name",
        cookie_key="bargain_bungalow_cookie_key",
        redirect_uri=redirect_uri,
    )
    return authenticator

Any help would be much appreciated!!

Got it working on localhost, but its givingv the 403 error when i try to run on the streamlit.app . Any possible issues ?