Skip to main content
Drop-in implementations for the three most common stacks. Every example here is real, runnable code — copy it, change the constants at the top, and ship.

What these samples do

Each implementation:
  1. Generates PKCE values
  2. Sends the user to /authorize
  3. Validates state and iss on the callback
  4. Exchanges the code at /token
  5. Stores the access + refresh tokens (in a session — your storage layer is up to you)
  6. Calls /api/public/v1/games/magic-the-gathering/decks with the access token
  7. Refreshes when the token expires, rotating the refresh token

Node.js (Express)

A complete server-side OAuth client.

package.json

app.js

Run it

Open http://localhost:3000/login and the flow takes over.

Python (Flask)

Same flow, idiomatic Python.

requirements.txt

app.py

Run it

curl (end-to-end manual flow)

When you want to see every byte on the wire. Useful for debugging.

What every sample gets right

Validates state

Compared against the value stored at flow start. Mismatch = abort.

Validates iss

Defends against mix-up attacks (RFC 9207).

Uses S256 PKCE

plain is forbidden. SHA-256 only.

Rotates refresh tokens

Every refresh stores the new token. The old one is dead.

Sends form-encoded body

Content-Type: application/x-www-form-urlencoded, not JSON.

Refreshes proactively

5 minutes before expiry, not after the API returns 401.
Treat these as starting points. Production code should add retry/backoff, structured logging that never logs tokens, and a real token store (database or encrypted Redis) instead of session storage.