Integrating Google OAuth 2.0 into a Python web application is one of the most effective ways to offer a seamless, secure, and familiar login experience for users. In this guide we’ll walk through every step—from creating credentials in the Google Cloud Console to writing clean, production‑ready Python code—so you can add “Sign in with Google” to your Flask or Django project in minutes. By the end of the article you’ll understand the OAuth 2.0 flow, how to verify ID tokens, and best practices for keeping your implementation safe and SEO‑friendly.
Why Choose Google OAuth 2.0 for Python Applications?
- Trusted identity provider: Over 2 billion users already have Google accounts, reducing friction and boosting conversion rates.
- Reduced password fatigue: Users never need to create or remember another password, which lowers support tickets.
- Built‑in security: Google handles password storage, multi‑factor authentication, and suspicious‑login detection.
- Rich user profile data: Access to email, name, profile picture, and locale with a single API call.
- SEO advantage: Faster login leads to lower bounce rates, longer session duration, and higher rankings for user‑centric signals.
Prerequisites Before You Start
- A Google account with access to the Google Cloud Console.
- Python 3.8+ installed on your development machine.
- Basic familiarity with either Flask or Django (the examples cover both).
- Virtual environment tools such as
venvorpipenv.
Step 1: Create OAuth 2.0 Credentials in Google Cloud Console
1.1 Enable the Google Identity Services API
Navigate to APIs & Services > Library and search for Google Identity Services. Click Enable to activate the API for your project.
1.2 Configure the OAuth consent screen
- Go to APIs & Services > OAuth consent screen.
- Select External (unless you’re building an internal app).
- Fill in the required fields: App name, Support email, and Authorized domains.
- Add the scopes you’ll request, e.g.,
openid,email,profile. - Save and continue; you can skip optional sections for a quick setup.
1.3 Generate a client ID and client secret
Under Credentials click Create credentials > OAuth client ID. Choose Web application** and set the following:
- Authorized JavaScript origins:
http://localhost:5000(or your production domain). - Authorized redirect URIs:
http://localhost:5000/auth/callback(Flask) orhttp://localhost:8000/accounts/google/login/callback/(Django).
Copy the Client ID and Client secret**; you’ll need them in your Python code.
Step 2: Install Required Python Packages
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install Flask==2.3.* # or Django==5.0.*
pip install google-auth google-auth-oauthlib google-auth-httplib2 requests
The google-auth family handles token verification, while requests is used for optional profile calls.
Step 3: Implement the OAuth Flow in Flask
3.1 Basic Flask app skeleton
from flask import Flask, redirect, url_for, request, session, jsonify
import os
import google.auth.transport.requests
from google.oauth2 import id_token
app = Flask(__name__)
app.secret_key = os.urandom(24)
# Load credentials from environment variables for security
GOOGLE_CLIENT_ID = os.getenv('GOOGLE_CLIENT_ID')
GOOGLE_CLIENT_SECRET = os.getenv('GOOGLE_CLIENT_SECRET')
REDIRECT_URI = 'http://localhost:5000/auth/callback'
3.2 Build the authorization URL
from urllib.parse import urlencode
@app.route('/login')
def login():
params = {
'client_id': GOOGLE_CLIENT_ID,
'redirect_uri': REDIRECT_URI,
'response_type': 'code',
'scope': 'openid email profile',
'access_type': 'offline',
'prompt': 'consent' # forces a refresh token on first login
}
auth_url = f"https://accounts.google.com/o/oauth2/v2/auth?{urlencode(params)}"
return redirect(auth_url)
3.3 Handle the callback and exchange the code for tokens
import requests
@app.route('/auth/callback')
def callback():
error = request.args.get('error')
if error:
return f"Error: {error}", 400
code = request.args.get('code')
token_endpoint = 'https://oauth2.googleapis.com/token'
data = {
'code': code,
'client_id': GOOGLE_CLIENT_ID,
'client_secret': GOOGLE_CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'grant_type': 'authorization_code'
}
token_response = requests.post(token_endpoint, data=data)
token_response.raise_for_status()
tokens = token_response.json()
id_info = verify_id_token(tokens['id_token'])
session['user'] = {
'sub': id_info['sub'],
'email': id_info['email'],
'name': id_info.get('name'),
'picture': id_info.get('picture')
}
return redirect(url_for('profile'))
3.4 Verify the ID token securely
def verify_id_token(token):
request_adapter = google.auth.transport.requests.Request()
try:
id_info = id_token.verify_oauth2_token(
token,
request_adapter,
GOOGLE_CLIENT_ID
)
return id_info
except ValueError as e:
# Token is invalid
raise RuntimeError(f"Invalid token: {e}")
3.5 Display a simple profile page
@app.route('/profile')
def profile():
user = session.get('user')
if not user:
return redirect(url_for('login'))
return f"""
Welcome, {user['name']}!
Email: {user['email']}
Logout
"""
3.6 Add a logout route
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('login'))
Step 4: Django Integration (Alternative)
4.1 Install Django‑allauth for a turnkey solution
pip install django-allauth
Allauth abstracts most of the OAuth boilerplate. Add the following to settings.py:
INSTALLED_APPS = [
# default Django apps …
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
]
SITE_ID = 1
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
LOGIN_REDIRECT_URL = '/'
SOCIALACCOUNT_PROVIDERS = {
'google': {
'SCOPE': ['profile', 'email'],
'AUTH_PARAMS': {'access_type': 'offline'},
'APP': {
'client_id': os.getenv('GOOGLE_CLIENT_ID'),
'secret': os.getenv('GOOGLE_CLIENT_SECRET'),
'key': ''
}
}
}
Include the URLs in urls.py:
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('allauth.urls')),
]
Run migrations and start the server. Users can now sign in via /accounts/login/ and select the Google button automatically rendered by Allauth.
Step 5: Secure Your OAuth Implementation
- Never hard‑code secrets: Store
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETin environment variables or a secret manager. - Validate the
stateparameter: Include a cryptographically randomstatetoken in the auth request and verify it on callback to protect against CSRF attacks. - Use HTTPS in production: Google blocks insecure redirect URIs, and browsers flag mixed‑content warnings.
- Limit token scopes: Request only the data you need (e.g.,
emailandprofile
Leave a Reply