Google Auth for Flask Site

Repl Talk Badge

Introduction

In this tutorial, I'm going to show you how you can authenticate users with Google on your Flask website. I will not be going over how to create a Flask application, how they work, or Python syntax.

Prerequisites

You should know the following before following this tutorial:

It would benefit you if you have used Google's Developer Console before, but you should be fine if you haven't.

Tutorial

Setting up a Django Application

Let's get started by creating our Google credentials.

Google Developer Console Setup

First, sign in to Google's Developer Console

If you haven't used the Developer Console before, Google will ask you a few questions. Complete those, then continue with the tutorial.

Configure OAuth2 Consent Screen

Create a project and configure your Google OAuth2 Consent Screen. Make sure that you select External user type unless the project is only for inside your Google organisation.

Fill out the required fields. For the Authorised Domain, put username.repl.co

OAuth2 Consent Screen gif

OAuth2 Credentials

Now, we need to get our credentials. Go back to the Credentials tab, and press Create CredentialsC. Select Oauth2 Client ID.

Select a Web Application, name your client and add a redirect URI. The URI will be your repl's url with /callback on the end. Example: https://Flask-Google-Auth-Demo.dillonb07.repl.co/callback Download the credentials you created. We will need the json file inside our repl.

Create Credentials gif

We've now finished with the Google Developer Console. Let's start making our Flask Application.

Creating our Flask App

Create a new Python repl with these imports: - repl.new/python


    import os
    import pathlib
    
    import requests
    from flask import Flask, session, abort, redirect, request, url_for
    from google.oauth2 import id_token
    from google_auth_oauthlib.flow import Flow
    from pip._vendor import cachecontrol
    import google.auth.transport.requests
  

These are the packages needed for the webserver and Google Authentication

Next, do the basic Flask application setup.


    app = Flask(__name__)
    app.config['SECRET_KEY'] = os.environ('SECRET_KEY') # Add this in the Secrets panel with a random string of letters, numbers and symbols.
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # This line is used to allow OAuthlib to work on http websites. You'll get an error without this if you try and login.

    # Our code will go here

    if __name__ == '__main__':
        app.run(port=3000, host='0.0.0.0', debug=True)
  

Upload the file that you downloaded from Google into Replit. It will be called something like client_secret_29774424209-u35ovepadeq7iuov24vs30ed24ja68fq.apps.googleusercontent.com.json.

Rename it to something more readable like client_secret.json.

Uploading secrets gif

Go into the file and get your Client ID and set it inside a variable.

Client ID gif

Now, create a variable called client_secrets_file that creates a path to your file.

    
      client_secrets_file = os.path.join(pathlib.Path(__file__).parent, 'client_secret.json')
    
  

Now, let's create a flow.


    flow = Flow.from_client_secrets_file(
       client_secrets_file=client_secrets_file,
       scopes=["https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email", "openid"],
        redirect_uri="https://Flask-Google-Auth-Demo.dillonb07.repl.co/callback" # Replace this with your URL
    )
  

This uses Google's oauthlib library to create a flow that sends the necessary data to Google servers.

Now, we're going to create a custom decorator for our non-existent endpoints.

    
def google_login_required(function):
    def wrapper(*args, **kwargs):
        if "google_id" not in session:
            return redirect(url_for('login'))
        else:
            return function()

    return wrapper
    
  

This code will create a decorator that we can use to make sure that the user is authenticated with Google before accessing the endpoint.

Now, let's work on our endpoints. We're going to have five endpoints.

  1. / - Homepage with login with Google button
  2. /login - Redirects the user to Google's OAuth2 Screen
  3. /callback - Sends and receives data to and from Google
  4. /logout - Logout of session and redirect to homepage
  5. /logged_in - Page that you must be logged in with Google to access

Let's start with the easiest endpoint. The homepage.

    
@app.route('/')
def index():
    return "You are logged out "
    
  

This is just a basic endpoint that displays a login button.

    
@app.route('/login')
def login():
    authorization_url, state = flow.authorization_url()
    session['state'] = state
    return redirect(authorization_url)
    
  

This endpoint sends the user to the Google OAuth2 Consent Screen using the flow that we created earlier.

    
@app.route('/callback')
def callback():
    flow.fetch_token(authorization_response=request.url)

    if not session['state'] == request.args['state']:
        abort(500)

    credentials = flow.credentials
    request_session = requests.session()
    cached_session = cachecontrol.CacheControl(request_session)
    token_request = google.auth.transport.requests.Request(session=cached_session)

    id_info = id_token.verify_oauth2_token(
        id_token=credentials._id_token,
        request=token_request,
        audience=GOOGLE_CLIENT_ID
    )

    session['google_id'] = id_info.get('sub')
    session['name'] = id_info.get('n
    
  

This endpoint is the most complicated. Here, we fetch Google's response and send the data to a Flask session.

    
@app.route('/logout')
def logout():
    session.clear()
    return redirect('/')
    
  

This endpoint clears the user's session data and redirects them to the homepage.

    
@app.route('/logged_in')
@google_login_required
def logged_in():
    return "You are logged in "
    
  

Here, we use the decorator we created to make sure that the user is logged in with Google to access the page.

We now have a fully functioning website! Run the program and try to log in with Google. You should be able to see the Logged in message after signing in with Google.

Here is the website I made: https://Flask-Google-Auth-Demo.dillonb07.repl.co

Repl Talk Badge
Back