jypi
  • Explore
ChatWays to LearnMind mapAbout

jypi

  • About Us
  • Our Mission
  • Team
  • Careers

Resources

  • Ways to Learn
  • Mind map
  • Blog
  • Help Center
  • Community Guidelines
  • Contributor Guide

Legal

  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Content Policy

Connect

  • Twitter
  • Discord
  • Instagram
  • Contact Us
jypi

© 2026 jypi. All rights reserved.

Fast API
Chapters

1Introduction to FastAPI

2Routing and Endpoints

3Request and Response Handling

4Dependency Injection

5Security and Authentication

Introduction to SecurityOAuth2 and JWTBasic AuthenticationUsing OAuth2 with PasswordOAuth2 ScopesAPI KeysRole-based Access ControlCORS in FastAPICSRF ProtectionRate Limiting

6Database Integration

7Testing FastAPI Applications

8Asynchronous Programming

9Deployment Strategies

10Real-world Applications and Projects

Courses/Fast API/Security and Authentication

Security and Authentication

17793 views

Learn to implement robust security and authentication mechanisms to protect your FastAPI applications.

Content

4 of 10

Using OAuth2 with Password

OAuth2 Password Flow — Slightly Chaotic, Highly Practical
4849 views
intermediate
humorous
software
sarcastic
gpt-5-mini
4849 views

Versions:

OAuth2 Password Flow — Slightly Chaotic, Highly Practical

Watch & Learn

AI-discovered learning video

Sign in to watch the learning video for this topic.

Sign inSign up free

Start learning for free

Sign up to save progress, unlock study materials, and track your learning.

  • Bookmark content and pick up later
  • AI-generated study materials
  • Flashcards, timelines, and more
  • Progress tracking and certificates

Free to join · No credit card required

OAuth2 with Password (the "I Know My Password, Give Me a Token" Flow)

You already met Basic Auth and flirted with OAuth2 + JWT. Now we're taking the next logical (and slightly spicy) step: using the OAuth2 password grant with FastAPI — the flow where the app takes a username/password and trades it for a token.

This lesson builds on the previous topics:

  • You know how to hash/verify passwords and why Basic Auth is insufficient for modern apps.
  • You know what JWTs are and why we sign/expire them.
  • You used dependency injection to provide a DB session or reusable services.

We're going to weave all that together into a practical, secure-ish implementation, and point out where to be extra cautious.


TL;DR (because we all skim first)

  • The client sends username/password to a token endpoint.
  • Server verifies credentials, returns an access token (often a signed JWT).
  • Protected routes depend on an OAuth2 bearer token dependency to get the current user.
  • Use HTTPS. Use hashed passwords. Prefer other grants for third-party login.

Why use the password grant? (and why not)

  • Good when your own first-party frontend and API are tightly coupled (e.g., official mobile app).
  • Bad when a third-party should authenticate — exposing user passwords to third parties is a non-starter.

Security soapbox: The password grant is convenient but risky if mishandled. Use HTTPS, short-lived tokens, refresh tokens, and consider more secure flows (Authorization Code + PKCE) for public clients.


The components (fast checklist)

  1. Token endpoint: accepts form data (username & password) — FastAPI uses OAuth2PasswordRequestForm for this.
  2. Password verification: compare submitted password against hashed password in DB (use passlib/bcrypt).
  3. Token creation: sign a JWT with expiry (we did JWT in the previous topic — reuse that logic).
  4. Dependency that extracts and validates token (OAuth2PasswordBearer) and returns current_user.

Example: Minimal but Practical Implementation

This assumes you already have:

  • A function to get a DB/user (e.g., get_user(username)).
  • Password hashing utilities (verify_password, get_password_hash).
  • JWT encode/decode helpers using python-jose or PyJWT (create_access_token, decode_token).
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import jwt, JWTError
from datetime import datetime, timedelta

app = FastAPI()

# token URL is the endpoint path where clients will send credentials
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token")

SECRET_KEY = "super-secret-key"  # replace with environment variable
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

# Fake DB for demo
fake_users_db = {
    "alice": {"username": "alice", "hashed_password": "fakehashedsecret", "disabled": False}
}

# helper to create JWT
def create_access_token(data: dict, expires_delta: timedelta | None = None):
    to_encode = data.copy()
    expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

# token endpoint
@app.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    user = fake_users_db.get(form_data.username)
    if not user or not verify_password(form_data.password, user["hashed_password"]):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token = create_access_token(data={"sub": user["username"]}, expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
    return {"access_token": access_token, "token_type": "bearer"}

# dependency to get current user from token
async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    user = fake_users_db.get(username)
    if user is None:
        raise credentials_exception
    return user

@app.get("/users/me")
async def read_users_me(current_user: dict = Depends(get_current_user)):
    return current_user

Note: verify_password and get_password_hash should come from passlib (bcrypt). tokenUrl must match the actual path where credentials are posted.


Scopes — giving tokens permission levels

OAuth2 supports "scopes"—tiny labels that tell the API what the token is allowed to do.

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/token", scopes={"items:read": "Read your items"})

# then in get_current_user you would inspect token payload for 'scopes'
# and verify the requested endpoint requires that scope

Use scopes to avoid "all-powerful" tokens when you just need to read public data.


Dependency Injection: Where it shines here

  • The token creation and verification lives as reusable functions.
  • Depends(oauth2_scheme) turns the raw header into a token string; get_current_user is a DI hook that fetches & validates the user.
  • You can inject DB sessions, caching, or revoked-token checkers into the same dependency chain.

Think of DI like a kitchen: you don't want to cook every dish with a different stove. You want a reliable stove (dependency) you can plug into recipes.


Pitfalls & Good Practices

  • Always use HTTPS. No debating this.
  • Never log passwords. Even in dev, don't log them.
  • Short token lifetimes + refresh tokens for prolonged sessions.
  • Consider refresh token revocation / rotation.
  • Prefer Authorization Code + PKCE for public clients (mobile/web) interacting with third-party services.

Expert take: "If someone asks your app to send them raw user passwords, run — in a secure, encrypted way — as far as you can." — Noted Security Teacher


Quick comparison (password grant vs other OAuth2 flows)

Flow Use case Exposes user password to client? Recommended for third-party apps?
Password Grant First-party apps where backend and frontend are trusted Yes No
Authorization Code + PKCE Mobile/web apps No Yes
Client Credentials Machine-to-machine N/A (no user) N/A

Closing — what you should remember (the recap rap)

  • Password grant = app trades credentials for a token — convenient for first-party clients.
  • Use OAuth2PasswordRequestForm for the token endpoint and OAuth2PasswordBearer to protect routes.
  • Use DI to inject token validation and DB access cleanly; it's how your code stays readable and testable.
  • Mind HTTPS, hash everything, and prefer safer flows for public clients.

Go forth and secure your endpoints! And when in doubt, ask: "Could this token compromise all the things if leaked?" If the answer is yes, make it shorter-lived or narrower-scoped.


version_name: "OAuth2 Password Flow — Slightly Chaotic, Highly Practical"

Flashcards
Mind Map
Speed Challenge

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Ready to practice?

Sign up now to study with flashcards, practice questions, and more — and track your progress on this topic.

Study with flashcards, timelines, and more
Earn certificates for completed courses
Bookmark content for later reference
Track your progress across all topics