ARCHIVED from builddistributedsystem.com on 2026-04-28 — URL: https://builddistributedsystem.com/tracks/securitor/tasks/task-24-1-2-oauth-authorization
TASK

Implementation

OAuth 2.0 lets users grant third-party apps limited access to their account without sharing their password. The authorization code flow sends the user to the auth server, which issues a short-lived code. The app then exchanges the code for an access token server-to-server.

Implement a node that handles the OAuth 2.0 authorization code flow:

// Step 1: Generate the authorization URL to redirect the user to
{ "type": "generate_auth_url", "msg_id": 1,
  "client_id": "abc123", "redirect_uri": "https://app.com/callback",
  "scopes": ["read","write"], "state": "xyz789" }
-> { "type": "auth_url_generated", "in_reply_to": 1,
    "url": "https://accounts.example.com/authorize?response_type=code&client_id=abc123&redirect_uri=https%3A%2F%2Fapp.com%2Fcallback&scope=read+write&state=xyz789" }

// Step 2: User approves -> exchange the code for tokens
{ "type": "exchange_code", "msg_id": 2,
  "code": "AUTH_CODE", "redirect_uri": "https://app.com/callback",
  "client_id": "abc123", "client_secret": "secret" }
-> { "type": "token_issued", "in_reply_to": 2,
    "access_token": "<token>", "token_type": "Bearer",
    "expires_in": 3600 }

// Validate a token has the required scope
{ "type": "check_scope", "msg_id": 3,
  "token": "ACCESS_TOKEN", "required_scope": "write" }
-> { "type": "scope_valid", "in_reply_to": 3, "has_scope": true }

Sample Test Cases

Generate authorization URLTimeout: 5000ms
Input
{
  "src": "client",
  "dest": "oauth",
  "body": {
    "type": "generate_auth_url",
    "msg_id": 1,
    "client_id": "abc123",
    "redirect_uri": "https://app.com/callback",
    "scopes": [
      "read",
      "write"
    ],
    "state": "xyz789"
  }
}
Expected Output
{"type": "auth_url_generated", "in_reply_to": 1, "url": "https://accounts.example.com/authorize?response_type=code&client_id=abc123&redirect_uri=https%3A%2F%2Fapp.com%2Fcallback&scope=read+write&state=xyz789"}
Exchange code for tokenTimeout: 5000ms
Input
{
  "src": "client",
  "dest": "oauth",
  "body": {
    "type": "exchange_code",
    "msg_id": 1,
    "code": "AUTH_CODE",
    "redirect_uri": "https://app.com/callback",
    "client_id": "abc123",
    "client_secret": "secret"
  }
}
Expected Output
{"type": "token_issued", "in_reply_to": 1, "access_token": "[A-Za-z0-9-_]+", "token_type": "Bearer", "expires_in": 3600}

Hints

Hint 1
Authorization URL must include: response_type=code, client_id, redirect_uri, scope (space-separated), state
Hint 2
URL-encode the redirect_uri in the authorization URL
Hint 3
Token exchange: POST to /token with code, redirect_uri, client_id, client_secret
Hint 4
check_scope: verify the token includes the required scope string
Hint 5
state parameter prevents CSRF — verify it matches on callback
OVERVIEW

Theoretical Hub

Concept overview coming soon

Key Concepts

OAuth 2.0authorization code flowPKCEaccess tokenscopetoken refresh
main.py
python
Implement OAuth 2.0 Authorization Flow - The Securitor | Build Distributed Systems