HomeBlog

Adding Google Authentication to Your FastAPI Application

8 min read
David Muraya Google Authentication Header Image
By David Muraya • January 27, 2025

Letting users sign in with their Google accounts can make your FastAPI app easier to use and more secure. Here's a clear, step-by-step guide to set it up.

What You'll Need

Before jumping in, make sure you have:

  • A basic understanding of FastAPI.
  • A Google account to use the Google Developer Console.
  • A FastAPI project already set up. You'll also need the httpx library for making HTTP requests. Install it with:
pip install httpx

Step 1: Set Up the Google Developer Console

First, you need to configure things in the Google Developer Console.

Create a Project

  • Head to the Google Developer Console.
  • Click "Select a project" at the top, then "New Project".
  • Name your project and hit "Create".

Configure the OAuth Consent Screen

Go to "OAuth consent screen" in the sidebar.

David Muraya OAuth consent screen Image
  • Fill in the required fields like app name and user support email.
  • Under "Scopes", add the "email" scope. You can add others like "profile" if you want more data.
  • Save your changes.

Create an OAuth Client ID

  • Navigate to "Credentials".

  • Click "Create credentials" and pick "OAuth client ID".

  • Select "Web application".

  • Enter your app's name.

  • For "Authorized JavaScript origins", use your app's origin, like https://localhost:5000.

  • For "Authorized redirect URIs", add your callback URL, like https://localhost:5000/app/auth/google/callback.

  • Click "Create" and copy your Client ID and Client Secret.

    David Muraya Client ID and Client Secret Image

Note: The redirect URI in your code must match this exactly, or it won't work.

Step 2: Add Google Authentication to FastAPI

Now, let's write the code to handle Google sign-ins in your FastAPI app.

Set Up Environment Variables

You'll need these variables:

  • GOOGLE_CLIENT_ID: Your Client ID from Google.
  • GOOGLE_CLIENT_SECRET: Your Client Secret from Google.
  • HOST: Your app's base URL, like https://localhost:5000.

Set them in a .env file or your environment. For a .env file, it'd look like:

GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
HOST=https://localhost:5000

Write the Authentication Routes

Here's the FastAPI code to handle the login and callback:


from fastapi import APIRouter, HTTPException, Request, status
from fastapi.responses import RedirectResponse
import httpx

router = APIRouter(prefix="/app")

# Replace these with your actual values or load from environment
GOOGLE_CLIENT_ID = "your_client_id"
GOOGLE_CLIENT_SECRET = "your_client_secret"
HOST = "https://localhost:5000"

GOOGLE_REDIRECT_URI = f"{HOST}/app/auth/google/callback"
GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/auth"
GOOGLE_TOKEN_URL = "https://accounts.google.com/o/oauth2/token"
GOOGLE_USER_INFO_URL = "https://www.googleapis.com/oauth2/v1/userinfo"
GOOGLE_SCOPE = "email"

@router.get("/auth/google/login", include_in_schema=False, response_class=RedirectResponse)
async def login_google():
    """Redirect the user to Google's login page."""
    google_oauth_url = (
        f"{GOOGLE_AUTH_URL}?response_type=code&client_id={GOOGLE_CLIENT_ID}"
        f"&redirect_uri={GOOGLE_REDIRECT_URI}&scope={GOOGLE_SCOPE}&access_type=offline"
    )
    return RedirectResponse(google_oauth_url, status_code=status.HTTP_302_FOUND)

@router.get("/auth/google/callback", include_in_schema=False)
async def auth_google(request: Request):
    """Handle the callback from Google after login."""
    code = request.query_params.get("code")
    if not code:
        raise HTTPException(status_code=400, detail="No authorization code found")

    # Swap the code for an access token
    data = {
        "code": code,
        "client_id": GOOGLE_CLIENT_ID,
        "client_secret": GOOGLE_CLIENT_SECRET,
        "redirect_uri": GOOGLE_REDIRECT_URI,
        "grant_type": "authorization_code",
    }
    async with httpx.AsyncClient() as client:
        response = await client.post(GOOGLE_TOKEN_URL, data=data)
        response_data = response.json()
        access_token = response_data.get("access_token")
        if not access_token:
            raise HTTPException(status_code=400, detail="No access token received")

    # Get user info with the access token
    async with httpx.AsyncClient() as client:
        user_info_response = await client.get(
            GOOGLE_USER_INFO_URL,
            headers={"Authorization": f"Bearer {access_token}"}
        )
        user_info = user_info_response.json()

    # Add your user handling logic here (e.g., create or log in user)
    return user_info  # For now, just return the info

How It Works

  • Login Route: Sends the user to Google's login page with your app's details.

  • Callback Route: Takes the code Google sends back, trades it for an access token, and uses that to grab the user's info (like their email).

Right now, the callback just returns the user info. You'll want to add logic to check if the user exists in your database. If not, create a new user with the Google ID and email. If they do exist, log them in. You could also set a cookie or token for session management.

What Happens When Users Sign In

Here's the flow after clicking "Sign in with Google":

  • You're sent to Google's sign-in page.
  • Google checks your credentials and sends an authorization code to your app.
  • Your app sends that code back to Google to get an access token.
  • The access token lets your app fetch the user's info.

A Few Notes

Your query mentioned saving the Google ID in the database, which is a good idea. The code you provided does that, but I've simplified it here to focus on the basics. If you want to use the full version with IP tracking and custom models (like UserInfoResponse), you'll need to define those separately. For example, UserInfoResponse might look like:


from pydantic import BaseModel

class UserInfoResponse(BaseModel):
    id: str
    email: str
    verified_email: bool
    picture: str

Also, your approach is solid, but I'd suggest adding a state parameter to the login URL to prevent CSRF attacks. Google supports it, and it's a simple security boost.

Wrap-Up

That's it! You've added Google Authentication to your FastAPI app. Users can sign in with their Google accounts, and you can use their info as needed. Test it out, and tweak it to fit your app - like adding more scopes or better error handling. Keep the access token secure, and you're good to go.

About the Author

David Muraya is a Solutions Architect specializing in Python, FastAPI, and Cloud Infrastructure. He is passionate about building scalable, production-ready applications and sharing his knowledge with the developer community. You can connect with him on LinkedIn.

Related Blog Posts

Enjoyed this blog post? Check out these related posts!

Full-Text Search: Using the Trigram Tokenizer Algorithm to Match Peoples Names
Managing Background Tasks in FastAPI: BackgroundTasks vs ARQ + Redis

Managing Background Tasks in FastAPI: BackgroundTasks vs ARQ + Redis

A practical guide to background processing in FastAPI, comparing built-in BackgroundTasks with ARQ and Redis for scalable async job queues.

Read More..

Adding Google Authentication to Your FastAPI Application

Adding Google Authentication to Your FastAPI Application

A guide to adding Google Authentication to your FastAPI app.

Read More..

Function Calling in Google Gemma3

Function Calling in Google Gemma3

Understanding Function Calling in Google Gemma3

Read More..

Contact Me

Have a project in mind? Send me an email at hello@davidmuraya.com and let's bring your ideas to life. I am always available for exciting discussions.

© 2025 David Muraya. All rights reserved.