TrueSpec

GitHub OAuth with FastAPI

OAuth2 Authorization Code flow with token exchange and user profile fetch

What You’ll Build

After following this guide, you will have a working implementation of github oauth with fastapi in your project. Implement GitHub OAuth login in a FastAPI application. Redirects users to GitHub for authorization, exchanges the code for an access token, fetches user profile data, and creates a session. Works with any Python web framework with minor adjustments.

Use Cases & Problems Solved

  • Protect routes so only authenticated users can access sensitive pages
  • Allow users to sign up, log in, and manage their accounts securely
  • Avoid storing raw passwords or building session management from scratch

Prerequisites

  • Python 3.10+
  • GitHub OAuth App (Settings > Developer settings)
  • FastAPI project

Step-by-Step Implementation

Install dependencies

The following snippet shows how to install dependencies. Copy this into your project and adjust the values for your environment.

pip install fastapi uvicorn httpx python-dotenv

GitHub OAuth flow

The following snippet shows how to github oauth flow. Copy this into your project and adjust the values for your environment.

# main.py
from fastapi import FastAPI, HTTPException
from fastapi.responses import RedirectResponse
import httpx, os

app = FastAPI()
CLIENT_ID = os.getenv("GITHUB_CLIENT_ID")
CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET")

@app.get("/auth/github")
def github_login():
    return RedirectResponse(
        f"https://github.com/login/oauth/authorize?client_id={CLIENT_ID}&scope=user:email"
    )

@app.get("/auth/github/callback")
async def github_callback(code: str):
    async with httpx.AsyncClient() as client:
        # Exchange code for token
        token_res = await client.post("https://github.com/login/oauth/access_token",
            json={"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "code": code},
            headers={"Accept": "application/json"})
        access_token = token_res.json().get("access_token")
        if not access_token:
            raise HTTPException(400, "Failed to get access token")

        # Fetch user profile
        user_res = await client.get("https://api.github.com/user",
            headers={"Authorization": f"Bearer {access_token}"})
        user = user_res.json()

    return {"login": user["login"], "name": user.get("name"), "avatar": user["avatar_url"]}

⚠️ Don’t Do This

❌ Passing client_secret in query params (visible in logs)

# Secret visible in server logs and browser history!
redirect_url = f'https://github.com/...?client_secret={CLIENT_SECRET}'

✅ Always send client_secret in the POST body

await client.post(url, json={
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET,  # In request body, not URL
    'code': code
})

Testing

Add these tests to verify your github oauth with fastapi implementation works correctly:

// __tests__/fastapi.test.ts
import { describe, it, expect } from 'vitest';

describe('GitHub OAuth with FastAPI', () => {
  it('should handle successful authentication', async () => {
    // Test the happy path
    const result = await authenticate({ email: 'test@example.com', password: 'valid' });
    expect(result.user).toBeDefined();
    expect(result.error).toBeNull();
  });

  it('should reject invalid credentials', async () => {
    const result = await authenticate({ email: 'test@example.com', password: 'wrong' });
    expect(result.user).toBeNull();
    expect(result.error).toBeDefined();
  });

  it('should handle missing fields', async () => {
    const result = await authenticate({ email: '', password: '' });
    expect(result.error).toBeDefined();
  });
});

Verification

uvicorn main:app --reload
# Visit http://localhost:8000/auth/github
# Authorize the app on GitHub
# Should redirect back with your GitHub profile data

Related Specs

Beginner

Firebase Auth with React

Google/GitHub sign-in, onAuthStateChanged listener, and route protection

Auth & Identity
Intermediate

Next.js Google OAuth Login

Complete Google OAuth flow with NextAuth.js, token handling, session management

Auth & Identity
Intermediate

Secure Session Management with Redis

Express sessions with Redis store, expiration, and fingerprinting

Auth & Identity