Skip to Content
API KoppelingOAuth Flow

OAuth Flow

Routix gebruikt OAuth 2.1 om externe applicaties te authenticeren. Er zijn twee flows beschikbaar, afhankelijk van je integratietype.


Flow 1: Authorization Code + PKCE

Wordt gebruikt wanneer je applicatie namens een Routix-gebruiker moet handelen. De gebruiker moet expliciet toestemming geven en de organisatie selecteren.

Verloop

Externe App Routix Auth Gebruiker │ │ │ ├── redirect naar /authorize ─►│ │ │ (client_id, scope, │ │ │ code_challenge, state) │ │ │ ├── consent scherm ──────►│ │ │ (app naam, scopes, │ │ │ org selector) │ │ │◄── goedkeuren + org ────┤ │ │ │ │◄── redirect met ?code= ─────┤ │ │ │ │ ├── POST /oauth/token ────────►│ │ │ (code, code_verifier) │ │ │◄── { access_token } ────────┤ │ │ │ │ ├── GET /api/v1/{vestiging}/..►│ (API Proxy) │ │◄── { data: [...] } ─────────┤ │

Stap 1: Genereer PKCE Challenge

Genereer een code verifier en challenge voordat je de flow start:

// Genereer code_verifier (43–128 tekens) const array = new Uint8Array(32); crypto.getRandomValues(array); const codeVerifier = btoa(String.fromCharCode(...array)) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); // Genereer code_challenge (SHA-256, base64url) const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier)); const codeChallenge = btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');

Stap 2: Redirect naar Authorize

Redirect de browser van de gebruiker naar:

https://api.routix.nl/auth/v1/oauth/authorize ?client_id=YOUR_CLIENT_ID &redirect_uri=https://jouwapp.nl/callback &response_type=code &code_challenge=BASE64URL_SHA256_HASH &code_challenge_method=S256 &scope=routix:accounts:read routix:orders:read &state=RANDOM_STATE_VALUE
ParameterVerplichtBeschrijving
client_idJaDe client ID van je OAuth-app (UUID)
redirect_uriJaMoet exact overeenkomen met een geregistreerde redirect URI
response_typeJaAltijd code
code_challengeJaBase64url-encoded SHA-256 hash van je code_verifier
code_challenge_methodJaAltijd S256
scopeJaSpatie-gescheiden lijst van gevraagde scopes
stateAanbevolenWillekeurige string om CSRF-aanvallen te voorkomen

Routix toont een consent-scherm waar de gebruiker:

  1. De applicatienaam en alle gevraagde scopes ziet
  2. Selecteert voor welke organisatie toegang wordt verleend (multi-tenant)
  3. De aanvraag goedkeurt of afwijst

Bij goedkeuring:

  • Er wordt een record aangemaakt in oauth_client_authorizations die de app koppelt aan de geselecteerde organisatie
  • De gebruiker wordt teruggestuurd naar je redirect_uri met ?code=xxx&state=xxx

Stap 4: Wissel Code in voor Tokens

curl -X POST https://api.routix.nl/auth/v1/oauth/token \ -H "Content-Type: application/json" \ -d '{ "grant_type": "authorization_code", "code": "AUTHORIZATION_CODE", "redirect_uri": "https://jouwapp.nl/callback", "client_id": "YOUR_CLIENT_ID", "client_secret": "routix_a1b2c3d4...", "code_verifier": "YOUR_ORIGINAL_CODE_VERIFIER" }'

Response:

{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "bearer", "expires_in": 3600, "refresh_token": "v1.MjQ0ZWY5..." }

Stap 5: Vernieuw Tokens

Access tokens verlopen na 1 uur. Gebruik de refresh token om een nieuwe op te halen:

curl -X POST https://api.routix.nl/auth/v1/oauth/token \ -H "Content-Type: application/json" \ -d '{ "grant_type": "refresh_token", "refresh_token": "v1.MjQ0ZWY5..." }'

Refresh tokens zijn eenmalig met rotatie. Elke refresh geeft een nieuwe refresh token terug.

Token Claims (Authorization Code)

De JWT wordt verrijkt door een Custom Access Token Hook die toevoegt:

{ "sub": "user-uuid", "aud": "authenticated", "role": "authenticated", "organization_id": "org-uuid", "oauth_client_id": "client-uuid", "oauth_scopes": ["routix:accounts:read", "routix:orders:read"] }

Deze claims worden afgedwongen door Row Level Security (RLS) in de database.


Flow 2: Client Credentials

Wordt gebruikt voor server-to-server (machine-to-machine) communicatie. Geen gebruikersinteractie nodig.

Verloop

Jouw Server Routix │ │ ├── POST /oauth-token ────────►│ │ (client_id, client_secret) │ │◄── { access_token } ────────┤ │ │ ├── GET /api/v1/{vestiging}/..►│ │◄── { data: [...] } ─────────┤

Token Aanvragen

curl -X POST https://api.routix.nl/functions/v1/oauth-token \ -H "Content-Type: application/json" \ -d '{ "grant_type": "client_credentials", "client_id": "YOUR_CLIENT_ID", "client_secret": "routix_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0" }'

Response:

{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "bearer", "expires_in": 3600, "scope": "routix:accounts:read routix:orders:read", "organization_id": "org-uuid", "branch_ids": ["branch-uuid-1", "branch-uuid-2"] }

Hoe Het Werkt

  1. Je server stuurt client_id + client_secret naar het token endpoint
  2. Routix verifieert het secret door SHA-256 hashes te vergelijken
  3. Een JWT wordt gebouwd met de organization_id, allowed_scopes en allowed_branch_ids van de app
  4. De JWT wordt gesigned met HS256 en teruggestuurd
  5. Gebruik het token om de API proxy aan te roepen

Token Claims (Client Credentials)

{ "iss": "supabase", "aud": "authenticated", "role": "authenticated", "sub": "app-uuid", "organization_id": "org-uuid", "oauth_client_id": "client-uuid", "oauth_scopes": ["routix:accounts:read"], "oauth_branch_ids": ["branch-uuid-1"], "oauth_app_name": "Mijn ERP Sync" }

Vergelijking

AspectAuthorization Code + PKCEClient Credentials
GebruikersinteractieJa (consent scherm)Nee
Token endpoint/auth/v1/oauth/token/functions/v1/oauth-token
Org bindingGeselecteerd door gebruiker bij consentUit app-registratie
Refresh tokensJa (30 dagen, roterend)Nee — vraag nieuw token aan
Use caseGebruikersgerichte apps, marketplaceBackend sync, BI, automatisering

Beveiligingsrichtlijnen

RichtlijnWaarom
Gebruik altijd PKCE met S256Verplicht voor Authorization Code flow. Plain challenges worden niet ondersteund.
Bewaar secrets veiligHet client secret wordt maar één keer getoond. Gebruik een secrets manager — zet het nooit in broncode.
Valideer de state parameterVoorkomt CSRF-aanvallen tijdens de redirect-flow.
Vraag minimale scopes aanVraag alleen de scopes aan die je applicatie daadwerkelijk nodig heeft.
Roteer secrets regelmatigGebruik het secret rotation endpoint om periodiek je client secret te vernieuwen.
Handel token-expiry afTokens verlopen na 1 uur. Refresh (Auth Code flow) of vraag een nieuw token aan (Client Credentials).
Stel secrets nooit bloot in frontend-codeDe Client Credentials flow mag alleen vanuit een backend-server worden gebruikt.
Last updated on