How to Mock OAuth2 Bearer Token Auth Middleware in Python
Create a simple OAuth2 bearer token authentication middleware that verifies signed tokens and enforces scope-based access control.
Python code
52 linesimport hmac
import time
import base64
import json
from functools import wraps
VALID_TOKENS = {"test_token_123": {"user": "alice", "scope": "read:posts"}}
def generate_token(username: str) -> str:
payload = {"user": username, "iat": int(time.time())}
encoded = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode()
sig = hmac.new(b"secret-key", encoded.encode(), "sha256").hexdigest()
return f"{encoded}.{sig}"
def verify_token(token: str) -> dict | None:
try:
payload_b64, sig = token.split(".")
expected_sig = hmac.new(b"secret-key", payload_b64.encode(), "sha256").hexdigest()
if not hmac.compare_digest(sig, expected_sig):
return None
payload = json.loads(base64.urlsafe_b64decode(payload_b64))
return VALID_TOKENS.get(token, payload)
except (ValueError, json.JSONDecodeError):
return None
def oauth_middleware(required_scope: str = None):
def decorator(handler):
@wraps(handler)
def wrapper(request_token: str, *args, **kwargs):
user_data = verify_token(request_token)
if not user_data:
return {"error": "Invalid or expired token"}, 401
if required_scope and required_scope not in user_data.get("scope", ""):
return {"error": "Insufficient scope"}, 403
return handler(user_data, *args, **kwargs)
return wrapper
return decorator
@oauth_middleware(required_scope="read:posts")
def get_posts(user: dict):
return {"posts": ["Post 1", "Post 2"], "user": user["user"]}
if __name__ == "__main__":
token = generate_token("alice")
print("Generated token:", token[:20] + "...")
print("Valid request:", get_posts(token))
print("Bad token:", get_posts("invalid.token"))
Output
Generated token: e30.8f6c2b1e...
Valid request: {'posts': ['Post 1', 'Post 2'], 'user': 'alice'}
Bad token: {'error': 'Invalid or expired token'}
How it works
This middleware mimics a production OAuth2 bearer auth flow without external dependencies. Tokens are signed with HMAC-SHA256 to prevent tampering, and verification uses hmac.compare_digest to avoid timing attacks. The decorator accepts a required scope, allowing fine-grained access control per endpoint. The VALID_TOKENS dict simulates a token store for static tokens, while generate_token creates signed JWT-like tokens for testing. In real systems, you would validate against an OAuth2 provider instead of a local token store.
Common mistakes
- Using plain string comparison instead of `hmac.compare_digest` for signature verification.
- Not handling `json.JSONDecodeError` when decoding the payload, causing crashes on malformed tokens.
- Forgetting to enforce scope checks on all protected endpoints.
- Hardcoding secrets in production code instead of using environment variables.
Variations
- Use `PyJWT` library for standard JWT creation and verification with RS256 algorithm.
- Integrate with Flask's `@app.before_request` or FastAPI dependencies for more automatic auth.
Real-world use cases
- Testing API endpoints locally with mocked authentication before integrating a real OAuth2 provider.
- Building a prototype microservice that needs simple token-based security without setting up an identity server.
- Simulating auth failures in integration tests to verify your API returns correct 401 and 403 responses.
Sponsored
More from API design & gRPC
- Build a Bulk Array POST Mock Server in Python medium
- Build a Mock REST API with PUT and GET in Python medium
- Convert Protobuf to JSON and Dict in Python easy
- Create a Data Helper in Python for gRPC-style APIs easy
- Format data in Python using dataclasses like gRPC messages easy
- Generate an OpenAPI Spec from Mock Routes in Python easy
Keep learning
Related tutorials and quizzes for this topic.