Authentication & Authorization — JWT and OAuth
627 words
3 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Authentication & Authorization — JWT and OAuth ## 🎯 Learning Objectives - Implement JWT-based authentication - Understand OAuth 2.0 flow - Protect API routes with token verification - Handle token refresh and logout ## 1. JWT — JSON Web Tokens A JWT is a self-contained token with three parts: `header.payload.sign...

Authentication & Authorization — JWT and OAuth
🎯 Learning Objectives
- Implement JWT-based authentication
- Understand OAuth 2.0 flow
- Protect API routes with token verification
- Handle token refresh and logout
1. JWT — JSON Web Tokens
A JWT is a self-contained token with three parts:
header.payload.signature.pseudoeyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.8x7wV3j... └── header ──┘└─── payload ───┘└── signature ──┘
Backend (Flask JWT)
python# pip install pyjwt import jwt from datetime import datetime, timedelta from functools import wraps SECRET_KEY = 'your-secret-key' # Use environment variable! def create_token(user_id): payload = { 'user_id': user_id, 'exp': datetime.utcnow() + timedelta(hours=24), 'iat': datetime.utcnow() } return jwt.encode(payload, SECRET_KEY, algorithm='HS256') def verify_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return payload['user_id'] except jwt.ExpiredSignatureError: return None # Token expired except jwt.InvalidTokenError: return None # Invalid token def token_required(f): @wraps(f) def decorated(*args, **kwargs): token = request.headers.get('Authorization', '').replace('Bearer ', '') user_id = verify_token(token) if user_id is None: return jsonify({'error': 'Invalid or expired token'}), 401 return f(user_id, *args, **kwargs) return decorated @app.route('/api/login', methods=['POST']) def login(): data = request.get_json() user = authenticate_user(data['username'], data['password']) if user: token = create_token(user['id']) return jsonify({'token': token}) return jsonify({'error': 'Invalid credentials'}), 401 @app.route('/api/profile') @token_required def profile(user_id): user = get_user(user_id) return jsonify(user)
Frontend (React)
javascriptasync function login(username, password) { const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); if (response.ok) { localStorage.setItem('token', data.token); return true; } throw new Error(data.error); } async function fetchProfile() { const token = localStorage.getItem('token'); const response = await fetch('/api/profile', { headers: { 'Authorization': `Bearer ${token}` } }); return response.json(); }
2. Practice Questions
Q1: What are the three parts of a JWT?Answer: Header (algorithm, type), Payload (claims like user_id, exp, iat), Signature (verifies token integrity). The token is base64url-encoded and separated by dots. Q2: How do you protect an API route with JWT?Answer: Create a decorator (@token_required) that extracts the token from the Authorization header, verifies it, and passes the user_id to the route function. Returns 401 if invalid. Q3: Where should you store JWT tokens on the frontend?Answer: Store inlocalStorage(simple but XSS-vulnerable) orhttpOnlycookies (more secure, CSRF-protected). SessionStorage is not persistent across tabs. Q4: What happens when a JWT expires?Answer: The server returns 401 Unauthorized. The frontend should catch this, redirect to login, or attempt to refresh the token using a refresh token (a longer-lived token stored separately). Q5: What is OAuth 2.0?Answer: An authorization framework where users grant limited access to their data on one service (e.g., Google) to another service (e.g., your app) without sharing passwords. Common for "Login with Google/Facebook" buttons. Q6: What's the difference between authentication and authorization?Answer: Authentication: "Who are you?" (login, verify identity). Authorization: "What are you allowed to do?" (permissions, roles). JWT handles authentication; you need separate logic for authorization (e.g., role checks). Q7: How do you implement token refresh?Answer: Issue two tokens: access token (short-lived, 15 min) and refresh token (long-lived, 7 days). When access token expires, use refresh token to get a new one without re-login. Store refresh token securely (httpOnly cookie). Q8: What security concerns exist with JWTs?Answer: (1) Token theft: anyone with the token can impersonate. (2) Weak secret: defeats signature verification. (3) No revocation: tokens are valid until expiry. (4) XSS: if stored in localStorage, cross-site scripting can steal tokens.
📐 Key Concepts
| Concept | Backend | Frontend |
|---|---|---|
| Token creation | jwt.encode(payload, key) | — |
| Token verification | jwt.decode(token, key) | — |
| Send token | — | Authorization: Bearer |
| Protect route | Decorator pattern | if (!token) redirect login |
| Store token | — | localStorage or httpOnly cookie |
🔗 Cross-References
- Next: File Uploads & Background Tasks Join Discord PreviousAdvanced BackendNextFile Uploads & Background Tasks