HomeBlog

Adding Google Authentication to Your FastAPI Application

8 min read

David Muraya Google Authentication Header Image

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.

Related Blog Posts

Enjoyed this blog post? Check out these related posts!

Adding middleware to FastAPI Applications: Process Time Headers, Security, and Compression

Adding middleware to FastAPI Applications: Process Time Headers, Security, and Compression

A practical guide to implementing middleware in FastAPI for better performance, security, and efficiency.

Read More..

Full-Text Search: Using the Trigram Tokenizer Algorithm to Match Peoples Names

Full-Text Search: Using the Trigram Tokenizer Algorithm to Match Peoples Names

Leveraging Full Text Search and Trigram Tokenization for Efficient Name Matching

Read More..

Deploying Reflex Front-End with Caddy in Docker

Deploying Reflex Front-End with Caddy in Docker

A step-by-step guide to building and serving Reflex static front-end files using Caddy in a Docker container

Read More..

Reflex Makes SEO Easier: Automatic robots.txt and sitemap.xml Generation

Reflex Makes SEO Easier: Automatic robots.txt and sitemap.xml Generation

Discover how adding your deploy URL in Reflex automatically generates robots.txt and sitemap.xml for easier SEO.

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.