SEOLizer Auth — Integrationsleitfaden

Wie ein Dienst sich an den zentralen Anmeldedienst auth.seolizer.de andockt (Single Sign-On).

Status: Der komplette Authorization-Code-Flow mit PKCE ist live: /authorize, /api/token, /.well-known/jwks.json und die OIDC-Discovery laufen produktiv. Client-Registrierung erfolgt derzeit per CLI durch einen Administrator (bin/client_add.php).

1. Grundprinzip

Ein angebundener Dienst (Client) betrachtet einen Nutzer nur dann als eingeloggt, wenn auth.seolizer.de eine gültige Login-Bestätigung liefert. Fehlt sie, leitet der Dienst den Nutzer zum zentralen Login weiter; nach erfolgreicher Anmeldung kehrt der Nutzer zum Dienst zurück. Technisch ist das ein OAuth-2.0-/OIDC-artiger Authorization-Code-Flow mit PKCE.

2. Voraussetzung: Client-Registrierung live (per Admin-CLI)

Ein Administrator registriert deinen Dienst einmalig. Danach erhältst du:

FeldBedeutung
client_idÖffentliche Kennung des Dienstes, z. B. word.
client_secretGeheimnis (nur für vertrauliche Server-Clients; niemals im Browser/Frontend).
redirect_uriWhitelist erlaubter Rücksprung-URLs, z. B. https://word.seolizer.de/auth/callback.
scopesErlaubte Rechte, z. B. openid profile email.

3. Ablauf des Logins live

  1. Nutzer ruft deinen Dienst auf. Kein gültiges Token vorhanden.
  2. Dienst erzeugt state (CSRF-Schutz) und einen PKCE-code_verifier + code_challenge (S256) und leitet weiter zu:
    https://auth.seolizer.de/authorize
        ?client_id=word
        &redirect_uri=https://word.seolizer.de/auth/callback
        &response_type=code
        &scope=openid%20profile%20email
        &state=RANDOM_STATE
        &code_challenge=BASE64URL_S256
        &code_challenge_method=S256
  3. Nutzer meldet sich zentral an (E-Mail/Benutzername + Passwort, optional MFA).
  4. auth.seolizer.de leitet zurück zur redirect_uri mit einem einmaligen Code:
    https://word.seolizer.de/auth/callback?code=AUTH_CODE&state=RANDOM_STATE
    Dienst prüft, dass state mit dem gesendeten übereinstimmt.
  5. Dienst tauscht den Code serverseitig gegen Tokens (siehe Abschnitt 5) und prüft deren Signatur. Erst danach gilt der Nutzer als eingeloggt.

4. Token-Arten

TokenZweckLaufzeit
access_tokenZugriff auf Dienste/APIs5–15 Min
id_tokenIdentitätsinfos über den Nutzer (JWT)5–15 Min
refresh_tokenErneuert Access-TokensTage–Wochen (widerrufbar)

JWT-Claims u. a.: sub (Benutzer-UUID, unveränderlich), iss=https://auth.seolizer.de, aud (deine client_id), iat, exp, jti, scope, roles.

5. Token-Endpunkt live

POST https://auth.seolizer.de/api/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://word.seolizer.de/auth/callback
&client_id=word
&client_secret=DEIN_SECRET
&code_verifier=DEIN_PKCE_VERIFIER

Antwort (JSON): access_token, id_token, refresh_token, token_type=Bearer, expires_in.

6. Tokens prüfen live

Der Dienst prüft die JWT-Signatur gegen die öffentlichen Schlüssel unter https://auth.seolizer.de/.well-known/jwks.json. Der private Schlüssel verlässt den Auth-Dienst nie. Prüfe zusätzlich immer:

7. Heute verfügbar live

Für erste Tests läuft bereits eine session-basierte Auth-API (Cookie + CSRF). Diese ist die Basis, auf der der Redirect-Flow aufsetzt.

Methode & PfadZweckStatus
GET /api/healthStatuscheck (inkl. DB)live
GET /api/csrfCSRF-Token für mutierende Requestslive
POST /api/auth/registerRegistrierung (E-Mail, Benutzername, Passwort)live
POST /api/auth/loginLogin per E-Mail ODER Benutzernamelive
POST /api/auth/logoutAbmeldenlive
GET /api/auth/meAktueller Nutzer inkl. roleslive
PATCH /api/auth/profileProfil ändern (Anzeigename, E-Mail, Benutzername)live
POST /api/auth/passwordPasswort ändern (aktuelles + neues)live
GET /authorizeRedirect-Login startet hierlive
POST /api/tokenCode gegen Tokens tauschenlive
GET /.well-known/jwks.jsonÖffentliche Signaturschlüssel (RS256)live
GET /.well-known/openid-configurationOIDC-Discoverylive
POST /api/revokeRefresh-Token widerrufen (RFC 7009)live
GET /logoutAbmelden (OIDC end_session)live

Beispiel: Login gegen die Session-API

Mutierende Requests brauchen den CSRF-Token aus /api/csrf im Header X-CSRF-Token und dasselbe Session-Cookie (Cookie-Jar).

# 1) CSRF-Token holen (setzt Session-Cookie)
CSRF=$(curl -s -c cj.txt https://auth.seolizer.de/api/csrf | jq -r .token)

# 2) Login
curl -s -b cj.txt -c cj.txt \
  -H "Content-Type: application/json" \
  -H "X-CSRF-Token: $CSRF" \
  -d '{"identifier":"testuser","password":"..."}' \
  https://auth.seolizer.de/api/auth/login

# 3) Aktuellen Nutzer abfragen
curl -s -b cj.txt https://auth.seolizer.de/api/auth/me

8. Abmelden live

Zwei Bausteine, je nach Bedarf:

a) Refresh-Token widerrufen — POST /api/revoke (RFC 7009)

Serverseitig aufrufen (Client-Authentifizierung). Antwort ist immer 200, auch bei unbekanntem Token.

POST https://auth.seolizer.de/api/revoke
Content-Type: application/x-www-form-urlencoded

token=DEIN_REFRESH_TOKEN
&token_type_hint=refresh_token
&client_id=word
&client_secret=DEIN_SECRET

Access-Tokens sind kurzlebige, zustandslose JWTs und laufen von selbst ab; sie werden nicht einzeln widerrufen.

b) Zentrale Abmeldung — GET /logout (OIDC end_session)

Beendet die zentrale Auth-Session und widerruft alle Refresh-Tokens des Nutzers. Der Nutzer wird zu post_logout_redirect_uri zurückgeleitet, sofern diese in der Whitelist des Clients steht (dieselbe Whitelist wie redirect_uri); andernfalls zur zentralen Anmeldeseite.

GET https://auth.seolizer.de/logout
    ?client_id=word
    &post_logout_redirect_uri=https://word.seolizer.de/auth/callback
    &state=RANDOM_STATE

Der Dienst sollte parallel seine eigene lokale Session beenden.

9. Sicherheitsregeln