Pravin Kunnure ✦

Mar 27, 2026 • 1 min read

FastAPI Security Made Easy: JWT, OAuth2, CORS, Rate-Limiting, and HTTPS

Secure your FastAPI API in 2026 with minimal code and maximum protection. Learn JWT authentication, OAuth2, CORS, rate-limiting, and HTTPS.

FastAPI is fast and powerful, but without proper security, it’s incomplete. This guide shows how to secure your API using JWT authentication, OAuth2, CORS, rate-limiting, and HTTPS—all with minimal code.

JWT + OAuth2: Secure Your Endpoints

JWT allows stateless authentication, and FastAPI makes OAuth2 integration simple.

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import jwt
from datetime import datetime, timedelta

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

SECRET_KEY = "secret"
ALGORITHM = "HS256"

def create_token(username: str):
 return jwt.encode({"sub": username, "exp": datetime.utcnow() + timedelta(minutes=30)}, SECRET_KEY, algorithm=ALGORITHM)

@app.post("/token")
def login(data: OAuth2PasswordRequestForm = Depends()):
 if data.username != "admin" or data.password != "password":
 raise HTTPException(400, "Invalid credentials")
 return {"access_token": create_token(data.username), "token_type": "bearer"}

@app.get("/secure")
def secure(token: str = Depends(oauth2_scheme)):
 try:
 payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
 return {"user": payload["sub"]}
 except:
 raise HTTPException(401, "Invalid token")

CORS: Control Who Can Access Your API

Without CORS, browsers block cross-origin requests.

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(CORSMiddleware, allow_origins=["http://localhost:3000"], allow_methods=["*"], allow_headers=["*"])

Rate-Limiting: Stop Abuse Before It Starts

Limit how often clients can hit your API.

from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter

@app.get("/limited")
@limiter.limit("5/minute")
def limited(): return {"message": "Too many requests will be blocked"}

HTTPS: Always Encrypt Traffic

Never deploy without HTTPS.

uvicorn main:app --host 0.0.0.0 --port 443 --ssl-keyfile=key.pem --ssl-certfile=cert.pem

Use Let’s Encrypt in production for free SSL certificates.


Checklist

  • Use JWT for authentication

  • Protect routes with OAuth2

  • Enable CORS for trusted domains

  • Add rate-limiting to prevent abuse

  • Always serve over HTTPS

Join Pravin on Peerlist!

Join amazing folks like Pravin and thousands of other builders on Peerlist.

peerlist.io/

It’s available... this username is available! 😃

Claim your username before it's too late!

This username is already taken, you’re a little late.😐

0

17

0