OAuth is one of the most widely used standards for authorizing access to a user’s data from one server to another server on the Internet. It is a protocol that allows users to grant third-party access to their server resources on a case-by-case basis. OAuth 2.0 is a more recent standard that provides a more secure and standardized approach. But in turn, has a workflow that is more complicated than OAuth 1.0’s, and thus it can be a little tricky to implement by yourself. There are a few different OAuth 2.0 authorization flows in existence. In this tutorial, we’ll learn how to implement Google login in Flask app.

We’ll first look at what OAuth is. Then, we’ll see how to implement Google login in Flask app with OAuthLib and Requests libraries.

What is OAuth?

OAuth is a standardized authorization protocol that provides a process for end-users to authorize third-party access to their server resources on their behalf. OAuth makes sure that all parties involved are protected. OAuth is oftentimes used for authorizing third-party login to websites and apps. OAuth is an open standardized, meaning it’s freely available to use and modify. It was built to be a simple solution to the complicated problem of authorization. The OAuth 2.0 framework was designed to address the problems of the previous version and provide users with a safe and secure authorization mechanism.

The beauty of OAuth is that it doesn’t actually share password data but instead uses authorization tokens to prove an identity between consumers and service providers. All other data remains securely encrypted and the token only includes the information needed for authorization.

Prerequisites 

Get Google’s OAuth client ID

Setting up an account with Google is the first step in actually being able to use their login systems and integrate them into your application. This can be accomplished by going to their developer console, in which you will be asked to fill out several fields and accept a few terms before being able to create an application.

Firstly, you have to create a Google Account and set up your Developer Console. Only then, you’ll be able to get OAuth 2.0 Client IDs. 

Follow these steps to get your new set of OAuth credentials:

  1. Go to Google Developer Console and create a new project.
  2. Then from the sidebar go to the APIs and services section and click on Credentials from the drop-down.
  1. From here click on the CREATE CREDENTIALS button and then select the OAuth client ID section. (If this is your first time creating an OAuth ID, you would be asked to configure a consent screen, which you can quickly do by following the instructions shown on the website itself. )
  1. Select Web Application as the application type and give it a name. Then, add the Authorized redirect URIs, we’ll just add the localhost link since this is only for test. Paste http://127.0.0.1:5000/callback there.
  1. Once you’re done, press the Create button and the OAuth client created should have been created and you should have gotten Your Client ID and Your Client Secret.
  2.  Now download the JSON file from there and keep it in the same folder as the file where we will code the application and change its name to “client_sceret.json”.

Getting the modules

There are a lot of modules that you will need to have to follow this article, tho few of them are likely to already be installed in some systems (like Linux). In any case, you should check/install them by running the given command.

To save yourself some time, you can create a file called requirements.txt and paste the following list in it then install it all at once rather than installing them one by one.

Flask==1.1.2
google-auth==1.27.0
google-auth-oauthlib==0.4.2
oauthlib==3.1.0pathlib==1.0.1vendor==0.1
requests==2.25.1
requests-oauthlib==1.3.0

Run the command to install all of the modules at once:

pip install -r requirements.txt

Let’s write our app

OAuth 2.0 is an increasingly popular authentication protocol and tho the OAuth 2.0 spec may be very complicated, the protocol is straightforward and is way easier than creating your own user authentication system. These scripts illustrate the interaction necessary to obtain and use OAuth 2.0 access tokens. 

We can start by importing all the modules we need. I have also commented on everything you might need to know about the code. You can also check if everything is installed and working at this point.

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

After successfully importing the modules we can start to implement the Google OAuth 2.0 login in our project.

app = Flask("Google Login App")  #naming our application
app.secret_key = "GeekyHuman.com"  #it is necessary to set a password when dealing with OAuth 2.0
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"  #this is to set our environment to https because OAuth 2.0 only supports https environments

GOOGLE_CLIENT_ID = "<your_client_id>"  #enter your client id you got from Google console
client_secrets_file = os.path.join(pathlib.Path(__file__).parent, "client_secret.json")  #set the path to where the .json file you got Google console is

flow = Flow.from_client_secrets_file(  #Flow is OAuth 2.0 a class that stores all the information on how we want to authorize our users
    client_secrets_file=client_secrets_file,
    scopes=["https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email", "openid"],  #here we are specifing what do we get after the authorization
    redirect_uri="http://127.0.0.1:5000/callback"  #and the redirect URI is the point where the user will end up after the authorization
)

Upon adding the above code to the file, we can then start to create our functions and pages to display our results.

def login_is_required(function):  #a function to check if the user is authorized or not
    def wrapper(*args, **kwargs):
        if "google_id" not in session:  #authorization required
            return abort(401)
        else:
            return function()

    return wrapper


@app.route("/login")  #the page where the user can login
def login():
    authorization_url, state = flow.authorization_url()  #asking the flow class for the authorization (login) url
    session["state"] = state
    return redirect(authorization_url)


@app.route("/callback")  #this is the page that will handle the callback process meaning process after the authorization
def callback():
    flow.fetch_token(authorization_response=request.url)

    if not session["state"] == request.args["state"]:
        abort(500)  #state does not match!

    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")  #defing the results to show on the page
    session["name"] = id_info.get("name")
    return redirect("/protected_area")  #the final page where the authorized users will end up


@app.route("/logout")  #the logout page and function
def logout():
    session.clear()
    return redirect("/")


@app.route("/")  #the home page where the login button will be located
def index():
    return "Hello World <a href='/login'><button>Login</button></a>"


@app.route("/protected_area")  #the page where only the authorized users can go to
@login_is_required
def protected_area():
    return f"Hello {session['name']}! <br/> <a href='/logout'><button>Logout</button></a>"  #the logout button 


if __name__ == "__main__":  #and the final closing function
    app.run(debug=True)

After adding the all given code in one file, we then have to the put JSON file we got from the Develop Console and the one with the code “app.py” in the same folder. And it’s done!

Output

Now to see the results, run the below command in the terminal to start the application:

python app.py  #Windows
python3 app.py  #Linux/Mac

And if the application successfully started it should look something like this:

Now go to the link specified which is http://127.0.0.1:5000/ and you should get a page like this:

As you can see our login button appears on the page. Try clicking on it and we would get redirected to Google’s authentication page which would look something like this:

Log in using your account and you would get redirected to the callback page which will intern send you to the protected_area page. And Here’s what it looks like:

Final Words

In this article, we talked about how OAuth works and provide examples of how it’s implemented. We also provided you with some resources that can help you better understand OAuth, so you can make more informed decisions about using it in your applications. But this is nowhere near the end of this, there’s a lot of room for improvement, like adding better security, more ways to log in, adding templates to the code, and there lot more that can be done here. You can also find documentation for this stuff very easily, so I’d recommend you to check those out. We hope this article on how to implement Google login in Flask app.

Here are some useful tutorials that you can read: