How to Mock OAuth 2.0 Device Code Flow in Python

A mock implementation of the OAuth 2.0 device authorization grant for testing authentication flows without a real provider.

Medium Python 3.9+ Aug 9, 2026 Auth & security at scale 13 views 0 copies

Python code

61 lines
Python 3.9+
import hashlib
import time
import uuid


class DeviceCodeFlowMock:
    def __init__(self):
        self.device_codes = {}

    def request_device_code(self, client_id, scope="read write"):
        device_code = uuid.uuid4().hex
        user_code = str(uuid.uuid4().int)[:8].upper()
        expires_in = 300
        interval = 5
        self.device_codes[device_code] = {
            "status": "pending",
            "created_at": time.time(),
            "expires_in": expires_in,
            "user_code": user_code,
            "client_id": client_id,
            "scope": scope,
        }
        return {
            "device_code": device_code,
            "user_code": user_code,
            "verification_uri": "https://example.com/device",
            "expires_in": expires_in,
            "interval": interval,
        }

    def verify_user_code(self, user_code):
        for device_code, details in self.device_codes.items():
            if details["user_code"] == user_code and details["status"] == "pending":
                if time.time() - details["created_at"] > details["expires_in"]:
                    details["status"] = "expired"
                    return False
                details["status"] = "approved"
                return True
        return False

    def poll_for_token(self, device_code):
        details = self.device_codes.get(device_code)
        if not details:
            return {"error": "invalid_device_code"}
        if time.time() - details["created_at"] > details["expires_in"]:
            details["status"] = "expired"
            return {"error": "expired_token"}
        if details["status"] == "approved":
            token = hashlib.sha256(device_code.encode()).hexdigest()
            return {"access_token": token, "token_type": "Bearer", "expires_in": 3600}
        if details["status"] == "pending":
            return {"error": "authorization_pending"}
        return {"error": "access_denied"}


if __name__ == "__main__":
    flow = DeviceCodeFlowMock()
    request = flow.request_device_code("client-123")
    print("Device code request:", request)
    print("User approval:", flow.verify_user_code(request["user_code"]))
    print("Token response:", flow.poll_for_token(request["device_code"]))

Output

stdout
Device code request: {'device_code': 'f3a7c9e1b2d840a5b6c7d8e9f0a1b2c3', 'user_code': 'A1B2C3D4', 'verification_uri': 'https://example.com/device', 'expires_in': 300, 'interval': 5}
User approval: True
Token response: {'access_token': 'a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0', 'token_type': 'Bearer', 'expires_in': 3600}

How it works

This mock class simulates the OAuth 2.0 device authorization grant, which lets users sign in on secondary devices like TVs or CLI tools. request_device_code creates a pending record and returns a user code plus verification URI. verify_user_code approves pending requests while enforcing expiry based on creation time. poll_for_token returns an approved token or appropriate error responses for pending, expired, or invalid states. Using a sha256 hash of the device code simulates a deterministic access token without a real authorization server.

Common mistakes

  • Forgetting to handle expired tokens in both verification and polling methods
  • Storing device codes in memory instead of a persistent store for multi-process production use
  • Returning a real token instead of a mock one for testing purposes

Variations

  1. Use a database or Redis to persist device code states across multiple service instances
  2. Add JWT-based access tokens instead of simple hash digests for realistic token generation

Real-world use cases

  • Testing CLI applications that require user browser-based authorization without a live OAuth provider
  • Simulating device login flows for smart TVs or IoT devices during integration testing
  • Creating a mock authentication service for local development and CI pipelines

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Auth & security at scale

Related tutorials and quizzes for this topic.