Authentication in Modern Web Applications
Security patterns and best practices
Authentication is the foundation of application security. After implementing various authentication systems, I've learned that the right approach depends on your specific requirements. Here's a practical guide to modern authentication patterns.
JWT: The Stateless Approach
JSON Web Tokens provide a stateless authentication mechanism. Here's a secure implementation:
import jwt
from datetime import datetime, timedelta
from fastapi import HTTPException, Depends
from fastapi.security import HTTPBearer
security = HTTPBearer()
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire, "type": "access"})
return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")
def create_refresh_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(days=7)
to_encode.update({"exp": expire, "type": "refresh"})
return jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")Always use short-lived access tokens with longer-lived refresh tokens for better security.
Password Security Best Practices
Hashing with Salt
import bcrypt
def hash_password(password: str) -> str:
salt = bcrypt.gensalt()
return bcrypt.hashpw(password.encode('utf-8'), salt).decode('utf-8')
def verify_password(password: str, hashed: str) -> bool:
return bcrypt.checkpw(
password.encode('utf-8'),
hashed.encode('utf-8')
)Rate Limiting
Implement rate limiting on authentication endpoints to prevent brute force attacks. Use tools like Redis for distributed rate limiting.
OAuth 2.0 Integration
OAuth provides secure third-party authentication. Here's a Google OAuth example:
from authlib.integrations.fastapi_oauth2 import OAuth2Token
from authlib.integrations.httpx_oauth2 import OAuth2Client
oauth2_client = OAuth2Client(
client_id=GOOGLE_CLIENT_ID,
client_secret=GOOGLE_CLIENT_SECRET,
authorize_url="https://accounts.google.com/o/oauth2/auth",
token_url="https://oauth2.googleapis.com/token",
)
@app.get("/auth/google")
async def google_auth():
redirect_uri = "http://localhost:8000/auth/callback"
return await oauth2_client.authorize_redirect(redirect_uri)
@app.get("/auth/callback")
async def google_callback(code: str):
token = await oauth2_client.fetch_token(code)
user_info = await get_google_user_info(token['access_token'])
# Create or update user in database
return {"user": user_info}Security Checklist
- Always use HTTPS in production
- Implement proper CORS policies
- Use secure, httpOnly cookies for sensitive data
- Implement account lockout after failed attempts
- Add two-factor authentication for sensitive operations
- Log authentication events for monitoring
- Regularly rotate secrets and keys
Final Thoughts
Authentication is not just about verifying identity - it's about building trust with your users. The patterns I've shared here have worked well in production applications, but always consider your specific security requirements and compliance needs. Security is an ongoing process, not a one-time implementation.