You have seen the login button on almost all the websites to manage the access of resources and keep the content secure from unauthorized access. So almost all the websites provide a login option before you can view any content and after login, you will be able to see the content that belongs to you or the content that is intended to view for public profiles.

This login process can be developed in two ways.

  1. Traditional method: In this method, the user will signup by filling out the signup form and then will log in using his username and password.
  2. Single sign-on: Here, users log in via platforms such as Google or Facebook using SSO, which leverages the OAuth 2.0 authentication method and in this article we are going to talk about the implementation of Google OAUTH 2.0 login for the python flask web server applications.

First, let’s talk about what is Oauth 2.0 before talking about Google Oauth 2.0 implementation in python.

What is OAuth 2.0 and its basics?

“OAuth 2.0 enables users to gain limited access to user accounts and delegates the authentication to the third-party account hosting the user’s information.”

Here, users share their basic account information like email ID, Full Name etc with other applications without revealing their original username and password. These features make it easy to use and secure. You have to remember only one username and password and then use that account to access all other applications.

Because of the above security feature, the single sign-on approach has become the most preferred method for all the service providers and users as it’s more secure and eliminates the need to by-heart the username and password for all the services and websites. All the overhead is pushed to the third party that is used for authentication.

In this article, we’ll talk about the implementation and setup of Oauth 2.0 in Python’s Flask framework and Google for the OAuth login.

The login process consists of the following steps:  

  1. Hit the Sign in with Google login button, you will be redirected to Google’s standard login page.
  2. Enter Google account credentials, and allow them to give consent to share their email and any information relevant to your application. 
  3. Once that information is passed to your application, you will be able to access that user’s information and can store it in the database for future reference and subsequent logins.

Prerequisites for Google Oauth Login in Python :

Enable Google APIs for your project

To call the Google APIs first you have to enable them in the API Console. Follow the below steps to enable the Google Plus API for your project.

  1. First, in the Google API Console, open the API Library.
  2. It will ask you to select a project or create a new one.
  3. Finally, on this page, you can find and enable the Google Plus API.

How to create authorization credentials

In order to use OAuth 2.0, we need to create authorization credentials. Follow the below steps to create credentials for your project, then only you will be able to access Google APIs using OAuth 2.0.

  1. First, visit the Credentials page.
  2. Click on Create Credentials then OAuth Client ID.
  3. For the application type field, you can select Web Application.
  4. Fill out the remaining form and finally hit the Create button. We must specify authorized redirect URIs, which are the endpoints to which the OAuth 2.0 server can send responses. These endpoints must adhere to Google’s validation rules.

When you are doing testing on the dev environment, specify URIs that belong to the dev or local machine, such as http://127.0.0.1:5000. In this article, we are using  http://127.0.0.1:5000/login/google/authorized the redirect URI.

After creating your credentials, store GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET securely. Use them in the next steps while writing the Python code.

Note: Do not store the GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in a publicly-accessible location. In addition, if you share the source code to your application — for example, on GitHub — store them in an environment file and add that environment file in .gitignore to avoid inadvertently sharing your client credentials.

To implement the Google login in your Flask application, follow the steps below. This code was written in Python version 3.9.1 so it might be possible you face some issues in a different version of python.

Step 1: Create a requirements.txt file in the root directory of your project to install all the required packages and add the below lines. 

Flask==2.1.2
Flask-Dance[sqla]==6.0.0
blinker==1.4
python-dotenv==0.18.0

Now, run the below command to install all the packages from requirements.txt.

pip3 install -r requirements.txt

Step 2: Create the .env file to store the environment variables. We will store the Google client_id and client_secret here, which we created in the steps above.

GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
secret_key=

In order to use the session in Flask, you need to set a secret key. A secret key should be as random as possible. You can use the following command to quickly generate a value.

$ python -c 'import os; print(os.urandom(16))'

Step 3: We have set up all the basic dependencies required for the Google OAuth implementation. Next, we will create a file named app.py.

  1. Add the below code inside app.py to import all the packages.
import os
from dotenv import load_dotenv
from flask import Flask, render_template, redirect, url_for
from flask_dance.contrib.google import make_google_blueprint, google
import logging

2. Fetch the value of environment variables and store them in python variables.

load_dotenv()
app = Flask(__name__)
client_id = os.getenv('GOOGLE_CLIENT_ID')
client_secret = os.getenv('GOOGLE_CLIENT_SECRET')
app.secret_key = os.getenv('secret_key')

3. You must set the OAUTHLIB_RELAX_TOKEN_SCOPE environment variable to account for Google changing the requested OAuth scopes.
Disable OAuthlib’s HTTPS verification by setting OAUTHLIB_INSECURE_TRANSPORT in the environment variable when running locally. Make sure you DO NOT leave this option enabled when running in production.

os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'

4. Add the below code to handle the Google login. Check in the index function if the user is already logged in. Then, pass the user information into the HTML template. Create a login method that will redirect the user to Google’s login page.

blueprint = make_google_blueprint(
    client_id=client_id,
    client_secret=client_secret,
    reprompt_consent=True,
    scope=["profile", "email"]
)
app.register_blueprint(blueprint, url_prefix="/login")

@app.route("/")
def index():
    google_data = None
    user_info_endpoint = '/oauth2/v2/userinfo'
    if google.authorized:
        google_data = google.get(user_info_endpoint).json()

    return render_template('index.j2',
                           google_data=google_data,
                           fetch_url=google.base_url + user_info_endpoint)

@app.route('/login')
def login():
    return redirect(url_for('google.login'))

if __name__ == "__main__":
    app.run()

Step 4: Create an HTML template to show the frontend page. Create the templates directory in the root folder of the project. Then, create the index.j2 file and add the below HTML code in that file.

<!doctype html>
<html class="no-js" lang="">

<head>
  <title>Google Oauth 2.0 Login for python Flask application</title>
  <style>
    @import url(https://fonts.googleapis.com/css?family=Roboto:500);
    body {
      font-family: "Roboto";
    }
    .detail {
      margin: 0;
      padding-left: 5px;
      border: solid gold 3px;
      background-color: beige;
    }
    .google-btn {
      width: 184px;
      height: 42px;
      background-color: #4285f4;
      border-radius: 2px;
      box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.25);
      display: block;
    }
    .google-btn .google-icon-wrapper {
      position: absolute;
      margin-top: 1px;
      margin-left: 1px;
      width: 40px;
      height: 40px;
      border-radius: 2px;
      background-color: #fff;
    }
    .google-btn .google-icon {
      position: absolute;
      margin-top: 11px;
      margin-left: 11px;
      width: 18px;
      height: 18px;
    }
    .google-btn .btn-text {
      float: right;
      margin: 11px 11px 0 0;
      color: #fff;
      font-size: 14px;
      letter-spacing: 0.2px;
      font-family: "Roboto";
    }
    .google-btn:hover {
      box-shadow: 0 0 6px #4285f4;
    }
    .google-btn:active {
      background: #1669f2;
    }
  </style>
</head>

<body>
  <h3>Example of Google Login in Python Flask Application</h3>
  {% if not google_data %}
    <p style="color:#333;">You are not logged in, Click on the below link to sign in with google.</p>
    <a href="/login" class="google-btn">
      <div class="google-icon-wrapper">
        <img class="google-icon" src="https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg"/>
      </div>
      <p class="btn-text"><b>Sign in with google</b></p>
    </a>
  {% else %}
    <p>Hi {{ google_data.name }}, [<strong>{{ google_data.email }}</strong>]. You have logged in successfully from your Google Account. Check your below details.</p>
  {% if google_data is not none %}
    <div class="detail">
      <p style="font-size: 15px; padding-bottom: 10px;">User info fetched from <strong>{{ fetch_url }}</strong></p>
      {% for key, value in google_data.items() %}
        <p><strong>{{ key }}</strong>: {{ value }}</p>
      {% endfor %}
    </div>
  {% endif %}
  {% endif %}

</html>

Step 5: It’s time to run the final Flask web application by running below command in your terminal.

$ python3 app.py

Now, you can access http://localhost:5000 in your web browser and try signing in with Google.

If you are familiar with GitHub then you can clone the complete working code from this GitHub repository.

Let me know if you have any issues with the implementation of this by writing in the comment section.

You can read more tips and tricks related to python here.