Topics in this subject
FastAPI 3 min read Updated 11 Aug 2026

Authentication and OAuth2

Implementing OAuth2 with Passwords and handling JWTs in FastAPI.

🧑‍🏫 Sabse pehle — simple mein samjho#

Authentication ke fundamentals wahi hain jo Node.js mein the: Password hash karo (Passlib library use karke) aur login ke time ek JWT token do (PyJWT use karke). FastAPI is process ko thoda aur standardize kar deta hai apne built-in OAuth2 tools ke sath. Jab tum FastAPI ka OAuth2 dependency use karte ho, to tumhara Swagger UI /docs page directly ek "Authorize" button dikhane lagta hai! Tum wahi se login karke saare protected routes test kar sakte ho bina Postman ke!

The FastAPI Security Module#

FastAPI provides standard security schemes out of the box. We will use OAuth2PasswordBearer, which simply tells FastAPI: "Look for an Authorization header that contains the word Bearer followed by a token."

from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

# We specify the URL where the client should send their username/password to get the token
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# Any route that depends on oauth2_scheme will automatically reject requests without a token!
@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):
    return {"token_provided": token}

The Full Auth Flow#

Here is a simplified overview of how to build a complete Auth system in FastAPI. You need two external libraries: passlib (for hashing) and PyJWT (for token generation).

1. Generating a Token on Login#

The login endpoint must accept a specific form format (OAuth2 standards).

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
import jwt # (PyJWT)

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # 1. Fetch user from DB using form_data.username
    # 2. Hash form_data.password and compare it using passlib
    
    if not valid_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
        
    # 3. Create the JWT
    token_data = {"sub": form_data.username} # 'sub' is standard for Subject (User)
    token = jwt.encode(token_data, "SECRET_KEY", algorithm="HS256")
    
    # 4. Return it strictly in this JSON format
    return {"access_token": token, "token_type": "bearer"}

2. A Dependency to Verify Tokens#

We create a dependency that extracts the token, verifies its signature, and returns the current user.

async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        # Verify the signature and decode the payload
        payload = jwt.decode(token, "SECRET_KEY", algorithms=["HS256"])
        username = payload.get("sub")
        if username is None:
            raise HTTPException(status_code=401, detail="Invalid auth credentials")
            
    except jwt.PyJWTError:
        raise HTTPException(status_code=401, detail="Token has expired or is invalid")
        
    # Fetch user from DB and return it
    # user = db.query(User).filter(User.username == username).first()
    return {"username": username}

3. Protecting Routes#

Now, any route that needs protection just injects get_current_user.

@app.get("/users/me")
async def read_users_me(current_user: dict = Depends(get_current_user)):
    # This only runs if the token was perfectly valid!
    return {"status": "authenticated", "user": current_user}