OAuth2 authorization code flow mock in Python
A minimal HTTP server that mocks the OAuth2 authorization code flow, issuing codes via /authorize and exchanging them for tokens at /token.
Python code
50 linesimport json
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
AUTH_CODE_STORE = {}
CLIENT_ID = "demo-client"
REDIRECT_URI = "http://localhost:8000/callback"
class OAuthHandler(BaseHTTPRequestHandler):
def do_GET(self):
parsed = urlparse(self.path)
if parsed.path == "/authorize":
params = parse_qs(parsed.query)
if params.get("client_id", [None])[0] == CLIENT_ID:
code = "auth_code_123"
AUTH_CODE_STORE[code] = params["redirect_uri"][0]
self.send_response(302)
self.send_header("Location", f"{params['redirect_uri'][0]}?code={code}")
self.end_headers()
else:
self.send_response(400)
self.end_headers()
self.wfile.write(b"Invalid client_id")
elif parsed.path == "/token":
length = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(length).decode()
params = parse_qs(body)
code = params.get("code", [None])[0]
if code in AUTH_CODE_STORE and params.get("redirect_uri", [None])[0] == AUTH_CODE_STORE[code]:
token = {"access_token": "access_xyz", "token_type": "Bearer", "expires_in": 3600}
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(token).encode())
else:
self.send_response(400)
self.end_headers()
self.wfile.write(b"Invalid code or redirect_uri")
else:
self.send_response(404)
self.end_headers()
def log_message(self, format, *args):
pass
if __name__ == "__main__":
server = HTTPServer(("localhost", 8000), OAuthHandler)
print("Mock OAuth2 server running on http://localhost:8000")
print(f"Authorize: http://localhost:8000/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}")
server.serve_forever()
Output
Mock OAuth2 server running on http://localhost:8000
Authorize: http://localhost:8000/authorize?client_id=demo-client&redirect_uri=http://localhost:8000/callback
How it works
This mock server implements the two key endpoints of the OAuth2 authorization code flow. The /authorize endpoint validates the client_id, stores the redirect_uri paired with a generated code, and issues a 302 redirect carrying the code. The /token endpoint reads the form-encoded body, checks that the code exists and the redirect_uri matches what was stored during authorization, then returns a JSON access token. AUTH_CODE_STORE is a simple in-memory dict that mimics how a real authorization server tracks codes before they are exchanged. This pattern lets you test OAuth2 clients locally without relying on an external identity provider.
Common mistakes
- Not checking that the redirect_uri matches exactly what was stored at /authorize time
- Using a fixed code like 'auth_code_123' instead of generating unique values per request
- Forgetting to read Content-Length and decoding the request body properly
- Returning 302 without setting the Location header correctly
Variations
- Use secrets.token_urlsafe(32) instead of a hardcoded code for better uniqueness
- Add an expire timestamp to codes and a cleanup routine to remove used codes
Real-world use cases
- Testing an OAuth2 client library locally without needing a real identity provider or network access.
- Simulating authorization flows in integration tests to validate redirect and token exchange logic.
- Prototyping an API that consumes OAuth2-protected resources before the production auth service is ready.
Sponsored
More from Auth & security at scale
- ACME LetsEncrypt Mock Challenge Server in Python medium
- AES GCM encryption and decryption in Python medium
- Build a Mock OIDC Userinfo Endpoint in Python with Flask easy
- ChaCha20-Poly1305 mock in Python medium
- ECDH key agreement in Python with cryptography medium
- Enforce TLS 1.2 Minimum in Python easy
Keep learning
Related tutorials and quizzes for this topic.