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_originsto 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¶
- Configure CORS to allow only your frontend domain.
- Set up HTTPS with Let’s Encrypt on a test server.
- Add rate limiting to your
/auth/loginendpoint (e.g. 5 requests per minute per IP).