Authentication & Security in FastAPI (JWT + OAuth2)

 

Introduction

In real-world applications, not all APIs should be public.You need authentication and security to:

  • Protect user data 
  • Restrict access
  • Verify identity

In this blog, we’ll implement JWT Authentication in FastAPI.The most commonly used method in modern APIs.

What is Authentication?

Authentication is the process of verifying who the user is.

Example:

  • Login with username & password
  • Server verifies credentials
  • Returns a token

What is JWT?

JWT (JSON Web Token) is a secure token used for authentication.

It contains:

  • Header
  • Payload (user data)
  • Signature

Example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...


Step 1: Install Dependencies

pip install python-jose passlib[bcrypt]
  • python-jose → JWT handling
  • passlib → Password hashing

Step 2: Password Hashing

from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_password(password: str):
return pwd_context.hash(password)

def verify_password(plain, hashed):
return pwd_context.verify(plain, hashed)

Step 3: Create JWT Token

from jose import jwt
from datetime import datetime, timedelta

SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"

def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=30)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)


Step 4: Fake User Database

fake_user = {
"username": "admin",
"password": hash_password("1234")
}


Step 5: Login Route

from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.post("/login")
def login(username: str, password: str):
if username != fake_user["username"] or not verify_password(password, fake_user["password"]):
raise HTTPException(status_code=401, detail="Invalid credentials")
token = create_access_token({"sub": username})
return {"access_token": token, "token_type": "bearer"}

Step 6: Verify Token (Dependency)

from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")

def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload["sub"]
except:
raise HTTPException(status_code=401, detail="Invalid token")

Step 6: Verify Token (Dependency)

from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")

def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload["sub"]
except:
raise HTTPException(status_code=401, detail="Invalid token")

How It Works

  1. User logs in → gets JWT token
  2. Sends token in request header
  3. FastAPI verifies token
  4. Grants access to protected routes

Example Request Header

Authorization: Bearer <your_token>

Common Mistakes

1. Storing plain passwords
2. Using weak secret keys
3. Not setting token expiry
4. Not protecting sensitive routes

Best Practices

1. Always hash passwords
2. Use environment variables for secrets
3. Set token expiration
4. Use HTTPS in production

Key Takeaways

  • JWT is widely used for API authentication
  • FastAPI provides built-in OAuth2 support
  • Passwords must be hashed securely
  • Dependencies help protect routes


Comments

Popular posts from this blog

Database Integration in FastAPI (SQLAlchemy CRUD)

Middleware & CORS in FastAPI

Python Data Handling