Add OAuth login to your FastAPI app in one command.
Project description
OAuth for Dummies
Add "Login with GitHub" and "Login with Google" to any FastAPI app in one command.
Quickstart | How OAuth Works | What is OAuth? | CLI Reference | Tutorial
Why this exists
Adding OAuth to a FastAPI app should not take an afternoon. But it does, because:
- The official OAuth 2.0 spec is 76 pages long
- Every tutorial shows a different approach
- Redirect URI mismatches waste hours of debugging
- Production auth libraries are overkill when you just need "Login with GitHub"
oauth-for-dummies solves this. One CLI command drops working OAuth routes into your project. Two lines of code to integrate. Done.
Quickstart
pip install oauth-for-dummies
cd your-fastapi-project
oauth-init
That scaffolds three files into your project:
your-fastapi-project/
oauth_config.py # provider credentials from .env
oauth_routes.py # login, callback, logout endpoints
oauth_example_app.py # working demo app (optional)
.env # template for your OAuth keys
Integrate into your existing FastAPI app with two lines:
from oauth_routes import router as oauth_router
app.include_router(oauth_router)
Run the example to see it work:
pip install fastapi uvicorn httpx python-dotenv
# edit .env with your OAuth credentials
uvicorn oauth_example_app:app --reload
# open http://localhost:8000
What is OAuth 2.0?
OAuth 2.0 is how "Login with Google" works. Instead of giving an app your password, you tell Google: "let this app see my name and email." The app never touches your password. It gets a temporary token instead.
+----------+ +--------------+
| You | "Login with GitHub" ----> | Your App |
| (User) | | (FastAPI) |
+----------+ +------+-------+
|
+---------------------+
v
+---------------+
| GitHub | "Allow this app?"
| OAuth Server | <-- You click "Yes"
+-------+-------+
|
v sends authorization code
+---------------+
| Your App | exchanges code for token
| (server) | uses token to get your profile
+-------+-------+
|
v
You're logged in. No password shared. Ever.
That's the entire OAuth 2.0 Authorization Code flow. This project implements it for you.
How OAuth 2.0 Works
Here's the step-by-step flow that happens when a user clicks "Login with GitHub":
sequenceDiagram
participant User
participant App as Your FastAPI App
participant GitHub as GitHub OAuth
User->>App: Clicks "Login with GitHub"
App->>GitHub: Redirects to /authorize (client_id, scope, state)
GitHub->>User: Shows consent screen
User->>GitHub: Clicks "Authorize"
GitHub->>App: Redirects to /callback?code=abc&state=xyz
App->>App: Verifies state parameter (CSRF protection)
App->>GitHub: POST /access_token (code + client_secret)
GitHub->>App: Returns access_token
App->>GitHub: GET /user (Bearer token)
GitHub->>App: Returns user profile (name, email, avatar)
App->>User: Creates session, shows profile page
Key concepts:
| Concept | What it means |
|---|---|
| Authorization Code | A short-lived, one-time code the provider sends to your app. Not the token itself. |
| Access Token | The actual key your app uses to call the provider's API. Obtained by exchanging the code. |
| State Parameter | A random string your app generates to prevent CSRF attacks. Verified on callback. |
| Scopes | Permissions you request. read:user = profile info, user:email = email address. |
| Redirect URI | The URL the provider sends the user back to. Must match exactly what you registered. |
Getting OAuth Credentials
GitHub OAuth Setup
- Go to github.com/settings/developers
- Click "New OAuth App"
- Set these values:
- Application name: anything (e.g.
My App) - Homepage URL:
http://localhost:8000 - Authorization callback URL:
http://localhost:8000/auth/github/callback
- Application name: anything (e.g.
- Copy Client ID and Client Secret into your
.envfile
Google OAuth Setup
- Go to console.cloud.google.com/apis/credentials
- Click "Create Credentials" > "OAuth Client ID"
- Application type: Web application
- Add authorized redirect URI:
http://localhost:8000/auth/google/callback - Copy Client ID and Client Secret into your
.envfile
API Reference
Routes
After running oauth-init, your app gets these endpoints:
| Endpoint | Method | Description |
|---|---|---|
/auth/github/login |
GET | Redirects user to GitHub's OAuth consent screen |
/auth/github/callback |
GET | Handles GitHub's redirect, exchanges code for token |
/auth/google/login |
GET | Redirects user to Google's OAuth consent screen |
/auth/google/callback |
GET | Handles Google's redirect, exchanges code for token |
/auth/logout |
GET | Clears session cookie, redirects to home |
Session Helper
from oauth_routes import get_session
@app.get("/dashboard")
async def dashboard(request: Request):
user = get_session(request)
if not user:
return RedirectResponse("/auth/github/login")
# user dict contains:
# - id: str (provider's user ID)
# - name: str (display name)
# - email: str (email address, may be None)
# - avatar: str (profile picture URL)
# - provider: str ("github" or "google")
return {"welcome": user["name"]}
CLI Reference
oauth-init # scaffold all providers + example app
oauth-init --provider github # only GitHub OAuth
oauth-init --provider google # only Google OAuth
oauth-init --no-example # skip the example app, just routes + config
oauth-init --dir ./path/to/project # scaffold into a specific directory
Generated files:
| File | Purpose | Lines |
|---|---|---|
oauth_config.py |
Loads provider credentials from .env, configures OAuth endpoints |
~45 |
oauth_routes.py |
FastAPI router with login, callback, logout, session management | ~150 |
oauth_example_app.py |
Complete working demo with login page and profile page | ~85 |
.env |
Template with all required environment variables | ~12 |
Security
The generated code includes these security measures out of the box:
- CSRF protection via the
stateparameter (random token verified on callback) - HTTP-only cookies for session IDs (not accessible via JavaScript)
- SameSite=Lax cookie policy (prevents cross-site request forgery)
- Server-side token exchange (client secret never exposed to the browser)
- One-hour session expiry (configurable via
max_age)
Note: The generated code uses in-memory session storage. For production, swap
_sessionsdict for Redis, PostgreSQL, or your database of choice.
Comparison with Other Libraries
| oauth-for-dummies | Authlib | OAuthLib | python-social-auth | |
|---|---|---|---|---|
| Use case | Add OAuth fast | Production auth | Spec compliance | Full social auth |
| Setup time | 30 seconds | 30+ minutes | 1+ hours | 30+ minutes |
| Lines to integrate | 2 | 15+ | 30+ | 20+ |
| Working demo included | Yes | No | No | No |
| Beginner-friendly | Yes | No | No | Moderate |
| CLI scaffolding | Yes | No | No | No |
| Dependencies | FastAPI + httpx | Many | Many | Many |
This is not a replacement for Authlib. Use oauth-for-dummies to get started fast, learn how OAuth works, and prototype. Use Authlib when you need production-grade token management, PKCE, or OpenID Connect compliance.
Tutorial
This repo includes a complete tutorial app that logs every step of the OAuth flow to your terminal:
git clone https://github.com/pranavkumaarofficial/oauth-for-dummies.git
cd oauth-for-dummies
pip install -r requirements.txt
cp .env.example .env
# add your OAuth credentials to .env
uvicorn app.main:app --reload
You'll see output like this for every login:
============================================================
STEP 1 — Redirect user to GitHub
============================================================
URL: https://github.com/login/oauth/authorize
client_id: abc12345...
redirect_uri: http://localhost:8000/auth/github/callback
scope: read:user user:email
state: kF9x2mQp...
============================================================
See also:
- How OAuth Works — visual explanation of every step
- Step-by-step Tutorial — build OAuth from scratch
Project Structure
oauth-for-dummies/
|-- oauth_for_dummies/ # pip-installable CLI package
| |-- cli.py # oauth-init command
| +-- scaffold/ # template files dropped into your project
| |-- oauth_config.py
| |-- oauth_routes.py
| +-- oauth_example_app.py
|
|-- app/ # tutorial app (learning resource)
| |-- main.py # FastAPI demo with UI
| |-- config.py # environment variable loader
| +-- auth/
| |-- routes.py # auth route handlers
| +-- storage.py # session storage
|
|-- providers/ # OAuth provider implementations
| |-- base.py # abstract OAuthProvider class
| |-- github.py # GitHub OAuth provider
| |-- google.py # Google OAuth provider
| +-- registry.py # provider auto-discovery
|
|-- tests/ # unit tests (20 tests, all passing)
|-- docs/ # tutorials and diagrams
+-- pyproject.toml # PyPI packaging configuration
Contributing
Contributions welcome. Some ideas:
- Add a provider — Discord, Spotify, Twitter/X, LinkedIn, Apple
- Improve the CLI — interactive mode,
--framework flasksupport - Write tests for the scaffold files
See CONTRIBUTING.md for setup instructions.
FAQ
Q: Is this production-ready? A: The generated code is fine for internal tools, prototypes, and small apps. For production at scale, swap the in-memory session store for a database and add HTTPS.
Q: Can I use this with Flask/Django? A: Not yet. Currently FastAPI only. Flask support is planned.
Q: What Python versions are supported? A: Python 3.9 and above.
Q: Do I need to understand OAuth to use this?
A: No. Run oauth-init, add your keys to .env, and it works. But if you want to understand what's happening, read the tutorial.
License
MIT — use it, learn from it, build on it.
If this saved you time, consider giving it a star on GitHub.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oauth_for_dummies-1.0.1.tar.gz.
File metadata
- Download URL: oauth_for_dummies-1.0.1.tar.gz
- Upload date:
- Size: 18.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28efb193c7657db30c0b565282f18f180fd9ce4bc52102bb1573a136008604d8
|
|
| MD5 |
e0d2f81bca513b99ab10c097afb1c565
|
|
| BLAKE2b-256 |
30ab6625b7a46d14f3a86dd1dd63ba7405d07ccf3171133dbb7924ce6ae01e21
|
Provenance
The following attestation bundles were made for oauth_for_dummies-1.0.1.tar.gz:
Publisher:
publish.yml on pranavkumaarofficial/oauth-for-dummies
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oauth_for_dummies-1.0.1.tar.gz -
Subject digest:
28efb193c7657db30c0b565282f18f180fd9ce4bc52102bb1573a136008604d8 - Sigstore transparency entry: 1342578670
- Sigstore integration time:
-
Permalink:
pranavkumaarofficial/oauth-for-dummies@ec1bb3996a498c7150d68700f0ac2416179344bb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/pranavkumaarofficial
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec1bb3996a498c7150d68700f0ac2416179344bb -
Trigger Event:
push
-
Statement type:
File details
Details for the file oauth_for_dummies-1.0.1-py3-none-any.whl.
File metadata
- Download URL: oauth_for_dummies-1.0.1-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea272927d5964add6439ce3e9e7f997fd5d607ee9c70cc2429c987aa98d60a95
|
|
| MD5 |
dac4dbd7345907c3f76e022ec09e3ce0
|
|
| BLAKE2b-256 |
f3f9b001d6c4fe3bf9b3bba8b8b5c18acb1d22b03acfd9164136513d57e5ada7
|
Provenance
The following attestation bundles were made for oauth_for_dummies-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on pranavkumaarofficial/oauth-for-dummies
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oauth_for_dummies-1.0.1-py3-none-any.whl -
Subject digest:
ea272927d5964add6439ce3e9e7f997fd5d607ee9c70cc2429c987aa98d60a95 - Sigstore transparency entry: 1342578678
- Sigstore integration time:
-
Permalink:
pranavkumaarofficial/oauth-for-dummies@ec1bb3996a498c7150d68700f0ac2416179344bb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/pranavkumaarofficial
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec1bb3996a498c7150d68700f0ac2416179344bb -
Trigger Event:
push
-
Statement type: