Skip to content

CORS, HTTPS, Rate Limiting

🎯 What You’ll Learn

  • Why CORS matters in modern web APIs and how to configure it in FastAPI
  • Why HTTPS is essential and how to enable it in production
  • How rate limiting protects your API from abuse and denial-of-service attacks

🌐 Step 1: Cross-Origin Resource Sharing (CORS)

🧠 What is CORS?

CORS (Cross-Origin Resource Sharing) is a browser security feature. By default, browsers block requests from one domain (e.g. frontend.com) to another (e.g. api.com).

CORS defines rules that tell the browser:

“It’s safe to allow requests from this origin.”

Without proper CORS configuration:

  • Your frontend app may fail to call your API
  • You risk exposing your API to unwanted domains if configured too loosely

🔧 How to Configure CORS in FastAPI

FastAPI provides a middleware for CORS:

📄 main.py

# Add imports
from fastapi.middleware.cors import CORSMiddleware

# ...

# Add allowed origins
origins = [
    "http://localhost:3000",  # e.g. frontend dev server
    "https://myfrontend.com", # Production frontend
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,        # Which domains can access
    allow_credentials=True,       # Allow cookies/headers
    allow_methods=["*"],          # Which HTTP methods
    allow_headers=["*"],          # Which headers
)

🔍 Best Practice

  • Restrict allow_origins to trusted domains (not ["*"] in production)
  • Only allow necessary methods and headers

🔒 Step 2: HTTPS Everywhere

🧠 Why HTTPS?

HTTPS encrypts traffic between client and server. Without HTTPS:

  • Passwords, tokens, and data can be intercepted (man-in-the-middle attacks)
  • Browsers will mark your site as insecure

🔧 How to Enable HTTPS

FastAPI itself doesn’t handle HTTPS — you typically use a reverse proxy like NGINX or Traefik.

Example NGINX config snippet:

server {
    listen 443 ssl;
    server_name api.myapp.com;

    ssl_certificate /etc/letsencrypt/live/api.myapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.myapp.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

🔍 Best Practice

  • Use Let’s Encrypt for free SSL certificates
  • Redirect all HTTP traffic to HTTPS
  • Always deploy FastAPI behind a secure proxy (not directly exposed)

Refer to FastAPI official guide for more details on how this works and how to implement it: About HTTPS - FastAPI


⚡ Step 3: Rate Limiting

🧠 Why Rate Limiting?

Rate limiting prevents:

  • Abuse (e.g. spamming login attempts)
  • Denial-of-service attacks
  • Excessive resource consumption

It ensures fair usage by limiting requests per user/IP.

🔧 How to Implement Rate Limiting in FastAPI

FastAPI doesn’t include rate limiting out of the box, but you can use libraries like SlowAPI:

pip install slowapi

📄 main.py

# Add imports
from slowapi import Limiter
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware

# Instantiate limiter
limiter = Limiter(key_func=get_remote_address)

# ...


app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, limiter._rate_limit_exceeded_handler)
app.add_middleware(SlowAPIMiddleware)

# Example usage
@app.get("/login")
@limiter.limit("5/minute")
def login():
    return {"message": "Login attempt"}

🔍 Best Practice

  • Apply stricter limits on sensitive endpoints (e.g. /login)
  • Use more generous limits for public endpoints (e.g. /docs)
  • Monitor logs for abuse patterns

🧠 Recap

You now know how to secure your API with:

  • CORS → Control which domains can call your API
  • HTTPS → Encrypt all traffic to prevent interception
  • Rate Limiting → Protect against abuse and denial-of-service

Together, these practices harden your API against common threats.


🧪 Practice Challenge

  1. Configure CORS to allow only your frontend domain.
  2. Set up HTTPS with Let’s Encrypt on a test server.
  3. Add rate limiting to your /auth/login endpoint (e.g. 5 requests per minute per IP).