Inloggen met BeID (OIDC)
BeID is een OpenID Connect-provider. Je gebruikt de Authorization Code-flow met PKCE — de aanbevolen flow voor zowel web-apps als publieke clients (SPA's, mobiel).
Endpoints
Lees deze bij voorkeur uit het discovery-document in plaats van ze hard te coderen.
/.well-known/openid-configuration/.well-known/jwks.json/oauth/authorizecode terug./oauth/tokencode in voor een id_token en access_token./oauth/userinfoBearer tokenStap 1 — PKCE voorbereiden
Genereer een code_verifier en daaruit een code_challenge (SHA-256, base64url). De challenge stuur je mee naar /oauth/authorize, de verifier pas naar /oauth/token.
import { randomBytes, createHash } from "node:crypto";
const verifier = randomBytes(32).toString("base64url");
const challenge = createHash("sha256").update(verifier).digest("base64url");Stap 2 — Authorize
GET https://id.becyber.nl/oauth/authorize
?client_id=beid_client_xxx
&redirect_uri=https://jouw-app.nl/callback
&response_type=code
&scope=openid profile email kyc
&state=<random-csrf-token>
&code_challenge=<challenge>
&code_challenge_method=S256Gebruik altijd state
Geef een willekeurigestate mee en controleer die bij de callback. Zo bescherm je tegen CSRF op de redirect.Stap 3 — Token-uitwisseling
{
"grant_type": "authorization_code",
"code": "<code uit de callback>",
"redirect_uri": "https://jouw-app.nl/callback",
"client_id": "beid_client_xxx",
"code_verifier": "<verifier uit stap 1>"
}Het antwoord bevat een ondertekend ID-token:
{
"access_token": "eyJhbGciOiJFZERTQS0...",
"id_token": "eyJhbGciOiJFZERTQS0...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "openid profile email kyc"
}Stap 4 — Token valideren
Verifieer elk token voordat je het vertrouwt:
- Handtekening tegen de JWKS (let op de
kidin de header). iss=https://id.becyber.nlaud= jouwclient_idexpnog niet verstreken
import { jwtVerify, createRemoteJWKSet } from "jose";
const JWKS = createRemoteJWKSet(
new URL("https://id.becyber.nl/.well-known/jwks.json"),
);
const { payload } = await jwtVerify(id_token, JWKS, {
issuer: "https://id.becyber.nl",
audience: CLIENT_ID,
});
// payload.sub, payload.email, payload.kyc_status, ...Refresh tokens
Vraag de scope offline_access aan om naast het access-token ook een refresh-token te krijgen. Daarmee verleng je de toegang zonder de gebruiker opnieuw te laten inloggen.
{
"grant_type": "refresh_token",
"refresh_token": "<refresh-token>",
"client_id": "beid_client_xxx"
}Rotatie & hergebruik-detectie
Elk refresh-token is eenmalig: bij gebruik krijg je een nieuw token en wordt het oude ingetrokken (rotatie). Wordt een al geroteerd token toch hergebruikt, dan beschouwt BeID dat als een lek en trekt alle refresh-tokens van die gebruiker bij die app in.Intrekken (RFC 7009)
Trek een refresh-token actief in via het revocation-endpoint:
{ "token": "<refresh-token>", "client_id": "beid_client_xxx" }Claims
| Claim | Betekenis |
|---|---|
sub | Unieke, stabiele gebruikers-id |
email | E-mailadres |
email_verified | Of het e-mailadres geverifieerd is |
name | Volledige naam |
kyc_level | none · basic · verified |
kyc_status | not_started … approved |
id_token_signing_alg_values_supported. Gebruik altijd de JWKS — sleutels kunnen roteren. Meer hierover op Beveiliging.