Python Google Oauth2 Login Integration

Written by

in

Looking to let users sign in to your Python web app with their Google accounts? Integrating Google OAuth2 not only streamlines the login experience but also boosts security and trust. In this guide, we’ll walk you through every step—from creating Google credentials to implementing a fully‑functional OAuth2 flow using popular Python frameworks such as Flask and Django. By the end, you’ll have a ready‑to‑deploy solution that improves user acquisition, reduces password fatigue, and aligns with modern best practices for authentication.

Why Choose Google OAuth2 for Your Python Application?

  • Universal reach: Billions of users already have Google accounts.
  • Secure token handling: OAuth2 uses short‑lived access tokens and refresh tokens, minimizing credential exposure.
  • Reduced friction: Users can log in with a single click, increasing conversion rates.
  • Compliance: Google’s OAuth2 implementation adheres to industry standards like OpenID Connect.

Prerequisites Before You Start

  1. Python 3.8+ installed on your development machine.
  2. A virtual environment (venv, pipenv, or poetry) to isolate dependencies.
  3. Basic familiarity with a Python web framework (Flask or Django).
  4. A Google Cloud project with the OAuth consent screen configured.

Step 1: Create Google OAuth2 Credentials

1.1 Set Up a Google Cloud Project

  • Visit Google Cloud Console and create a new project.
  • Navigate to APIs & Services > OAuth consent screen. Choose “External” for public apps.
  • Fill out the required fields (App name, Support email, Authorized domains) and save.

1.2 Generate Client ID and Secret

  • Go to APIs & Services > Credentials and click “Create Credentials > OAuth client ID”.
  • Select “Web application” as the application type.
  • Enter a name (e.g., “MyPythonApp”).
  • Under Authorized redirect URIs, add the callback URL your app will use, e.g. http://localhost:5000/auth/callback for Flask or http://localhost:8000/accounts/google/login/callback/ for Django.
  • Click “Create” and note the generated Client ID and Client Secret. Store them securely (e.g., in environment variables).

Step 2: Install Required Python Packages

Both Flask and Django have dedicated extensions that simplify OAuth2 integration. Choose the one that matches your stack:

# For Flask
pip install Flask-OAuthlib==0.9.6
# For Django
pip install social-auth-app-django==5.4.0
# Common dependency
pip install python-dotenv

We’ll demonstrate implementations for both frameworks, so you can pick the one that fits your project.

Step 3: Implementing Google OAuth2 in Flask

3.1 Project Structure

my_flask_app/
│
├─ app.py
├─ .env
└─ templates/
   └─ index.html

3.2 Configure Environment Variables

# .env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
SECRET_KEY=your-flask-secret-key

3.3 Flask Application Code

import os
from flask import Flask, redirect, url_for, session, request, render_template
from flask_oauthlib.client import OAuth
from dotenv import load_dotenv

load_dotenv()  # Load .env variables

app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY')

# OAuth configuration
oauth = OAuth(app)
google = oauth.remote_app(
    'google',
    consumer_key=os.getenv('GOOGLE_CLIENT_ID'),
    consumer_secret=os.getenv('GOOGLE_CLIENT_SECRET'),
    request_token_params={
        'scope': 'openid email profile'
    },
    base_url='https://www.googleapis.com/oauth2/v1/',
    request_token_url=None,
    access_token_method='POST',
    access_token_url='https://oauth2.googleapis.com/token',
    authorize_url='https://accounts.google.com/o/oauth2/auth',
)

@app.route('/')
def index():
    user = session.get('google_user')
    return render_template('index.html', user=user)

@app.route('/login')
def login():
    return google.authorize(
        callback=url_for('authorized', _external=True)
    )

@app.route('/auth/callback')
def authorized():
    resp = google.authorized_response()
    if resp is None or resp.get('access_token') is None:
        return 'Access denied: reason={} error={}'.format(
            request.args['error'],
            request.args.get('error_description')
        )
    session['google_token'] = (resp['access_token'], '')
    user_info = google.get('userinfo')
    session['google_user'] = user_info.data
    return redirect(url_for('index'))

@google.tokengetter
def get_google_oauth_token():
    return session.get('google_token')

if __name__ == '__main__':
    app.run(debug=True)

3.4 Simple HTML Template

<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Google OAuth2 with Flask</title>
</head>
<body>
    {% if user %}
        <h2>Welcome, {{ user['name'] }}!</h2>
        <p>Email: {{ user['email'] }}</p>
        <img src="{{ user['picture'] }}" alt="Profile picture">
    {% else %}
        <a href="{{ url_for('login') }}">Sign in with Google</a>
    {% endif %}
</body>
</html>

Step 4: Implementing Google OAuth2 in Django

4.1 Install and Configure Social‑Auth

First, add the required apps to INSTALLED_APPS and configure authentication backends.

# settings.py
INSTALLED_APPS = [
    # … other apps …
    'social_django',
]

AUTHENTICATION_BACKENDS = (
    'social_core.backends.google.GoogleOAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

# Google OAuth2 keys (use environment variables for production)
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.getenv('GOOGLE_CLIENT_ID')
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.getenv('GOOGLE_CLIENT_SECRET')

# Redirect URL after login
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

# Optional: request additional profile fields
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    'email',
    'profile',
]

4.2 URL Configuration

# urls.py
from django.urls import path, include
from django.contrib import admin
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('social_django.urls', namespace='social')),
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
]

4.3 Template for Login/Logout

<!-- templates/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django Google OAuth2</title>
</head>
<body>
    {% if user.is_authenticated %}
        <h2>Hello, {{ user.get_full_name|default:user.username }}!</h2>
        <p>Email: {{ user.email }}</p>
        <a href="{% url 'logout' %}">Logout</a>
    {% else %}
        <a href="{% url 'social:begin' 'google-oauth2' %}">Sign in with Google</a>
    {% endif %}
</body>
</html>

Step 5: Handling Tokens and User Data Securely

Regardless of framework, follow these best practices to keep authentication data safe:

  • Never hard‑code credentials. Use environment variables or secret managers.
  • Validate ID tokens. Use Google’s public keys to verify the token signature and claims.
  • Store minimal user data. Typically, you only need the Google sub (unique user ID), email, and name.
  • Implement token refresh. Access tokens expire after an hour; use the refresh token to obtain a new one without re‑prompting the user.

Step 6: Common Pitfalls and How to Debug Them

6.1 Mismatched Redirect URI

If you receive redirect_uri_mismatch, double‑check that the URI registered in Google Cloud exactly matches the one your app sends (including http:// vs https:// and trailing slashes).

6.2 Invalid Client Secret

Make sure the client secret is copied correctly and that you’re not using the “Web client” secret for a mobile

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *