OAuth 2.0 — Schritt für Schritt
Mit dem Authorization-Code-Flow + PKCE greift eine Dritt-App im Namen eines aYOUne-Nutzers auf die API zu, ohne dessen Passwort zu kennen. Der gewährte Zugriff wird bei der Freigabe immer auf Scope ∩ Rechte des Nutzers ∩ Paket begrenzt und im Token eingefroren — ein Dritt-App-Token erbt nie die vollen Nutzerrechte.
1. App registrieren
Registrieren Sie Ihre App unter Entwickler → Apps. Sie erhalten eine client_id (oac_...). Für lokale Entwicklung ist ein Public-Client (nur PKCE, kein Secret) am einfachsten. Hinterlegen Sie Ihre Redirect-URI, z.B. http://localhost:8410/callback, und die gewünschten Scopes.
2. PKCE erzeugen
Pro Anmeldeversuch einen zufälligen code_verifier und daraus den code_challenge (SHA-256, base64url). S256 ist Pflicht — plain wird abgelehnt.
import crypto from 'crypto';
const b64url = (b) => b.toString('base64').replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'');
const verifier = b64url(crypto.randomBytes(32)); // geheim halten
const challenge = b64url(crypto.createHash('sha256').update(verifier).digest());
const state = b64url(crypto.randomBytes(16)); // CSRF-Schutz
3. Authorize-URL (Browser)
Leiten Sie den Nutzer zum Consent-Screen. Er meldet sich an und bestätigt die Scopes.
https://login.ayoune.app/oauth/authorize
?response_type=code
&client_id=oac_...
&redirect_uri=http://localhost:8410/callback
&scope=crm.consumers.view openid
&state=<state>
&code_challenge=<challenge>
&code_challenge_method=S256
4. Code gegen Token tauschen
Der Provider ruft Ihre Redirect-URI mit ?code=...&state=... auf. Prüfen Sie state, dann tauschen Sie den Code (mit dem code_verifier) gegen ein Token.
curl -X POST https://auth.ayoune.app/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=authorization_code \
-d code=<code> \
-d code_verifier=<verifier> \
-d client_id=oac_... \
-d redirect_uri=http://localhost:8410/callback
# confidential-Clients zusätzlich: -d client_secret=<secret>
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJ...",
"scope": "crm.consumers.view openid"
}
5. Scope-begrenzter API-Call
Der Access-Token trägt nur den gewährten Scope. Ein Call außerhalb davon liefert 403.
curl -H "Authorization: Bearer <access_token>" \
https://crm-api.ayoune.app/consumers?limit=3
6. Token erneuern & widerrufen
# Erneuern (Rotation)
curl -X POST https://auth.ayoune.app/oauth/token \
-d grant_type=refresh_token -d refresh_token=<refresh_token> -d client_id=oac_...
# Widerrufen
curl -X POST https://auth.ayoune.app/oauth/revoke \
-d token=<access_or_refresh_token> -d client_id=oac_...
Discovery
Alle Endpoints sind self-describing (RFC 8414):
curl https://auth.ayoune.app/.well-known/oauth-authorization-server
Scopes
Scopes sind aYOUne-Rechte (modul.entity.action, mit Wildcards crm.consumers.* / crm.*) plus die OIDC-Standard-Scopes openid / profile / email (→ /oauth/userinfo).
Referenz-App
Eine lauffähige Minimal-App (Node/Express) mit dem kompletten Flow liegt im Monorepo unter tooling/oauth-reference-app/ — kopieren, client_id eintragen, npm start.