Skip to content

Oauth_jwt


OAuth 2.0 is the industry standard for authorization - allowing third-party applications to access user resources without sharing passwords.

The Problem OAuth Solves
=======================
Before OAuth:
──────────────────
"Login with Facebook"
User enters Facebook password
MyApp sees: password
Problems:
• MyApp has full account access
• If MyApp is breached, password stolen
• Can't revoke access without changing password
─────────────────────────────────────────
With OAuth 2.0:
──────────────────
"Login with Facebook"
Facebook shows: "MyApp wants to access your name and email"
User approves
MyApp gets: limited access token
Benefits:
• MyApp never sees password
• User can revoke access anytime
• Limited permissions

Authorization Code Flow
=====================
┌──────────┐ ┌──────────────┐
│ User │ │ Auth │
│(Browser) │ │ Server │
└────┬─────┘ │ (Google, │
│ │ Facebook) │
│ 1. Click "Login with Google" │ │
│────────────────────────────────▶│
│ │ 2. Show │
│ 3. Redirect │ consent │
│◀────────────────────────────────│ screen │
│ (consent screen) │ │
│ │ │
│ 4. User grants permission │ │
│────────────────────────────────▶│ │
│ │ │
│ 5. Redirect with code │ │
│◀────────────────────────────────│ ?code= │
│ code=abc123 │ abc123 │
│ │ │
│ │ │
│ 6. Exchange code for tokens │ │
│────────────────────────────────▶│ │
│ │ │
│ 7. Return tokens │ │
│◀────────────────────────────────│ { │
│ {access_token, │ access_ │
│ refresh_token} │ token:.. │
│ │ } │

Client Credentials Flow (Machine-to-Machine)

Section titled “Client Credentials Flow (Machine-to-Machine)”
Client Credentials Flow
=====================
Used for server-to-server communication
┌──────────────┐ ┌──────────────┐
│ My Server │ │ Auth Server │
└───────┬──────┘ └──────┬───────┘
│ │
│ POST /oauth/token │
│ Content-Type: application/x-www-form │
│ │
│ grant_type=client_credentials │
│ &client_id=myapp │
│ &client_secret=secret123 │
│────────────────────────────────────────▶│
│ │
│ { │
│ "access_token": "eyJhbG...", │
│ "token_type": "Bearer", │
│ "expires_in": 3600 │
│ } │
│◀────────────────────────────────────────│
PKCE (Proof Key for Code Exchange)
==================================
Adds security for public clients (no client secret)
┌─────────────────────────────────────────────────────────────┐
│ 1. Generate random string (code_verifier) │
│ code_verifier = dBjftJeZ4CVP-mB92K27uhbUJU1p1r │
│ │
│ 2. Create hash (code_challenge) │
│ code_challenge = BASE64URL(SHA256(code_verifier)) │
│ │
│ 3. Authorization request includes code_challenge │
│ │
│ 4. Auth server stores code_challenge │
│ │
│ 5. Token request includes code_verifier │
│ │
│ 6. Auth server verifies code_verifier matches │
│ original code_challenge │
└─────────────────────────────────────────────────────────────┘
This prevents authorization code interception attacks!

JWT = Header.Payload.Signature
═══════════════════════════════
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
════════════════════════╬═══════════════════════════════════╬═══════════════════════════════════════════════════════
Header Payload Signature
─────────────────────────────────────────────────────────────
HEADER: Algorithm and token type
───────────────────────────────
{
"alg": "HS256", // HMAC using SHA-256
"typ": "JWT"
}
─────────────────────────────────────────────────────────────
PAYLOAD: Claims (data)
─────────────────────
{
"iss": "https://auth.example.com", // Issuer
"sub": "user-123", // Subject (user ID)
"aud": "my-api", // Audience
"exp": 1700000000, // Expiration
"iat": 1699999999, // Issued at
"nbf": 1699999999, // Not before
"jti": "unique-token-id", // JWT ID
// Custom claims
"name": "John Doe",
"role": "admin",
"permissions": ["read", "write"]
}
─────────────────────────────────────────────────────────────
SIGNATURE: Verify token wasn't tampered
──────────────────────────────────────────
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret_key
)
AlgorithmTypeUse Case
HS256SymmetricSimple apps, same server
RS256AsymmetricDistributed systems, microservices
ES256Elliptic CurveMobile apps, smaller tokens
# HS256 (Symmetric - same key for sign/verify)
import jwt
secret = "my_secret_key"
# Create token
token = jwt.encode(
{"user_id": "123", "role": "admin"},
secret,
algorithm="HS256"
)
# Verify token
decoded = jwt.decode(token, secret, algorithms=["HS256"])
print(decoded) # {'user_id': '123', 'role': 'admin'}
# RS256 (Asymmetric - private key sign, public key verify)
import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
# Load keys
with open("private_key.pem", "rb") as f:
private_key = serialization.load_pem_private_key(
f.read(), password=None, backend=default_backend()
)
with open("public_key.pem", "rb") as f:
public_key = serialization.load_pem_public_key(
f.read(), backend=default_backend()
)
# Create token with private key
token = jwt.encode(
{"user_id": "123"},
private_key,
algorithm="RS256"
)
# Verify with public key
decoded = jwt.decode(token, public_key, algorithms=["RS256"])

Scopes limit what the access token can do.

OAuth Scopes
===========
Request:
─────────────────────────────────────────
GET /oauth/authorize?
client_id=myapp&
redirect_uri=https://myapp.com/callback&
response_type=code&
scope=read:profile write:profile read:email
Available scopes (defined by auth server):
─────────────────────────────────────────
┌─────────────────┬──────────────────────────────────┐
│ Scope │ Description │
├─────────────────┼──────────────────────────────────┤
│ read:profile │ Read user profile info │
│ write:profile │ Update user profile │
│ read:email │ Read email address │
│ read:contacts │ Read contacts list │
│ publish │ Publish content │
└─────────────────┴──────────────────────────────────┘
User Consent Screen:
─────────────────────────────────────────
"MyApp wants to access your account:"
☑ Read your profile
☑ Update your profile
☑ Read your email
[Allow] [Cancel]

Token Types Comparison
=====================
┌─────────────────────────────────┬─────────────────────────────────┐
│ Access Token │ Refresh Token │
├─────────────────────────────────┼─────────────────────────────────┤
│ Short-lived (15 min - 1 hour) │ Long-lived (days - weeks) │
│ │ │
│ Included in API requests │ Used to get new access tokens │
│ │ │
│ Never stored long-term │ Stored securely server-side │
│ │ │
│ If stolen: limited damage │ If stolen: can get new access │
│ │ (but can be revoked) │
└─────────────────────────────────┴─────────────────────────────────┘
Token Lifecycle:
─────────────────────────────────────────
1. User logs in
2. Receive: access_token + refresh_token
3. Use access_token for API calls
4. Access token expires (e.g., 1 hour)
5. Use refresh_token to get new access_token
6. Repeat 3-5 until refresh_token expires
7. User must log in again
Refreshing Tokens
=================
┌──────────┐ ┌──────────────┐
│ Client │ │ Auth Server │
└────┬─────┘ └──────┬───────┘
│ │
│ POST /oauth/token │
│ Content-Type: application/x-www-form │
│ │
│ grant_type=refresh_token │
│ &refresh_token=rt_abc123 │
│ &client_id=myapp │
│────────────────────────────────────────▶│
│ │
│ Validate refresh token: │
│ - Not expired? │
│ - Not revoked? │
│ - Belongs to this client? │
│ │
│ { │
│ "access_token": "eyJhbG...", │
│ "token_type": "Bearer", │
│ "expires_in": 3600, │
│ "refresh_token": "rt_xyz789", ← New refresh token
│ "scope": "read:profile" │
│ } │
│◀────────────────────────────────────────│

OAuth & JWT Security Checklist
=============================
✓ Use HTTPS for all OAuth endpoints
✓ Use PKCE for mobile/SPA apps
✓ Validate all tokens server-side
✓ Short-lived access tokens (< 1 hour)
✓ Long-lived refresh tokens (with rotation)
✓ Store refresh tokens securely
✓ Implement token revocation
✓ Validate audience (aud claim)
✓ Check expiration (exp claim)
✓ Use RS256 for distributed systems

  1. OAuth 2.0 - Authorization framework for delegated access
  2. Authorization Code Flow - Web apps with user involvement
  3. Client Credentials - Machine-to-machine
  4. PKCE - Mobile/SPA security
  5. JWT - Compact, URL-safe tokens
  6. Access tokens - Short-lived, for API calls
  7. Refresh tokens - Long-lived, for getting new access tokens
  8. Scopes - Limit permissions

Next: Chapter 38: Secrets Management