DEV Community

Cover image for Flask App Login with Google
Marianna
Marianna

Posted on

Flask App Login with Google

Social authentication has one big advantage - you don't have to worry about user data, all the backend work is done for you! And almost everyone these days has a Google account so it would be really handy for your users to have this option!😊
So let's begin!

Step 1
First thing first you need to get your Google credentials details - Client ID and Client Secret. Go to Google Developers website and in the Credentials click on 'Create credentials. Select 'OAuth client ID'. 👇
Google credentials

You may have to create OAuth Consent Screen. Just enter your Flask app name and your email address in the user support & developer email and click 'Save and continue'.

OAuth consent screen

After that go back to credentials tab and edit your OAuth Client ID. Add new authorized URI to redirect your logins through:
Authorized redirect URIs
And we're done! Now let's create our app!

Step 2
Run the following in your command line:
pip install -U Flask Authlib requests

Create new folder for your app and open it in your favorite IDE:

mkdir flask-google-login
cd flask-google-login
code .
Enter fullscreen mode Exit fullscreen mode

Step 3
In your project directory create new folder templates and in this folder createindex.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
    <link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles.css') }}">
    <title>Flask app</title>
</head>
<body>
        <div align="center">
            <a href="google/" class="login-btn" style="text-decoration:none;">
                <img id="google" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/2048px-Google_%22G%22_Logo.svg.png"
            alt="Google"
            style="width:50px;height:50px;">
            <div class="btn-text">
                Login with Google
            </div>
            </a> 
        </div>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

Also in the working directory create another folder static and add styles.css file:

.login-btn {
    justify-content: center;
    flex-direction: row;
    display: flex;
    background-color: rgb(255, 255, 255);
    justify-content: center;
    align-items: center;
    width: 220px;
    padding: 10px;
    box-shadow: 3px 3px 3px rgb(170, 170, 170);
    border-radius: 15px;
}
.btn-text {
    justify-content: center;
    padding: 10px;
    font-family: 'Poppins', sans-serif;
    color: rgb(85, 85, 85);
}
Enter fullscreen mode Exit fullscreen mode

Step 4
In the main working directory create app.py file:

from flask import Flask, render_template, url_for, redirect
from authlib.integrations.flask_client import OAuth
import os


app = Flask(__name__)
app.secret_key = os.urandom(12)

oauth = OAuth(app)

@app.route('/')
def index():
    return render_template('index.html')
Enter fullscreen mode Exit fullscreen mode

To be able to authorize our users we need to create an unique secret key. to do that we simply use 12 randomly generated characters.
After that we will create the index function that will render our index.html page.

Step 5
Then we will create two functions that will handle authentication with Google. To get your Google Client ID and Secret go to Google Credentials click on the download icon and cope your credentials!

@app.route('/google/')
def google():

    GOOGLE_CLIENT_ID = 'YOUR GOOGLE CLIENT ID'
    GOOGLE_CLIENT_SECRET = 'YOUR GOOGLE CLIENT SECRET'

    CONF_URL = 'https://accounts.google.com/.well-known/openid-configuration'
    oauth.register(
        name='google',
        client_id=GOOGLE_CLIENT_ID,
        client_secret=GOOGLE_CLIENT_SECRET,
        server_metadata_url=CONF_URL,
        client_kwargs={
            'scope': 'openid email profile'
        }
    )

    # Redirect to google_auth function
    redirect_uri = url_for('google_auth', _external=True)
    print(redirect_uri)
    return oauth.google.authorize_redirect(redirect_uri)

@app.route('/google/auth/')
def google_auth():
    token = oauth.google.authorize_access_token()
    user = oauth.google.parse_id_token(token)
    print(" Google User ", user)
    return redirect('/')
Enter fullscreen mode Exit fullscreen mode

After all this run your app and go to http://localhost:5000/ and you should be able to see something like this:
Google Login
After clicking on the button you will be redirected to the Google Login page:
Google Login page
That's it! Hope you liked it and happy coding!😀

Top comments (3)

Collapse
 
mcoliver profile image
Michael Oliver • Edited

Nice! Little addition though. Google now requires a nonce and it helps to store the user in a session var so you can later reference it.

Step 4 add the import for generate_token and session

from flask import Flask, render_template, url_for, redirect, session
from authlib.common.security import generate_token
Enter fullscreen mode Exit fullscreen mode

Modify Step 5 def google()

@app.route('/google/')
def google():
....
    # Redirect to google_auth function
    redirect_uri = url_for('google_auth', _external=True)
    print(redirect_uri)
    session['nonce'] = generate_token()
    return oauth.google.authorize_redirect(redirect_uri, nonce=session['nonce'])

@app.route('/google/auth/')
def google_auth():
    token = oauth.google.authorize_access_token()
    user = oauth.google.parse_id_token(token, nonce=session['nonce'])
    session['user'] = user
    print(" Google User ", user)
    return redirect('/')
Enter fullscreen mode Exit fullscreen mode
Collapse
 
pmbyrd profile image
Perriesha Byrd

Thank you! Helpful update/tip. Worked for me when I was receiving an error message of missing parameter 'nonce' if I recall correctly.

Collapse
 
olney1 profile image
Ben

Great article! Does the ‘user’ variable the way you have coded it retrieve the name and email of the signed in user?