presseportale/dev/migration 2026/10-LEGACY-API-KUNDEN.md
Kevin Adametz 5b8bdf4182
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
12-05-2026 Frontend dev
2026-05-12 18:32:33 +02:00

6.7 KiB
Raw Permalink Blame History

10 Legacy-API-Kunden & Zugriffsbereinigung

Ausgangspunkt

Das Legacy-System speichert API-Zugriffe nicht applikationsseitig. In Produktion ist Symfony-Logging deaktiviert (logging_enabled: false, sfNoLogger). API-Nutzung ist daher nicht zuverlässig aus der Anwendung rekonstruierbar.

Stattdessen wird der API-Cutover aus den migrierten Daten abgeleitet:

  • Legacy-API-User sind in users.registration_type = apiuser bzw. über die Rolle api-only erkennbar.
  • Legacy-API-Keys wurden bewusst nicht übernommen.
  • Legacy-API-Credentials wie apiReadAccess / apiWriteAccess wurden nicht 1:1 pro User persistiert, sondern in neue Sanctum-Abilities übersetzt.
  • Zahlungs-/Freigabestatus kann nur über importierte legacy_invoices bzw. später über Grandfathering-Daten bewertet werden.

Legacy-Regeln

Im alten Symfony-Frontend gilt:

  • API-fähige Routen sind in apps/frontend/config/routing.yml mit api_access: true markiert.
  • ApiAccessFilter weist X-ApiKey auf nicht-API-Routen mit HTTP 501 ab.
  • ApiKeyGuardAuthFilter liest X-ApiKey und sucht sfGuardUserProfile.api_key.
  • Wird ein Profil gefunden, wird dessen User für den Request eingeloggt.
  • Wenn bereits eine gültige Web-Session existiert, kann die API technisch auch ohne gültigen API-Key laufen, sofern Credentials passen.
  • SecureApiAccessFilter verlangt:
    • GET / HEADapiReadAccess
    • POST / PUT / DELETEapiWriteAccess
    • andere Methoden → HTTP 405
  • Einzelne Actions verlangen zusätzlich Symfony-Credentials wie editor.
  • ApiKeyGuardAuthFilter prüft nicht selbst is_active.

Neue Bewertungsregel

Für den Cutover erhalten nur noch Kunden Zugriff, die im migrierten System fachlich freigabefähig sind:

  1. Kandidat ist registration_type = apiuser oder hat Rolle api-only.
  2. User ist aktiv (is_active = true).
  3. Die letzte importierte Legacy-Rechnung des Users hat status = paid.

Alle anderen Kandidaten werden nicht automatisch freigeschaltet:

  • needs_review: aktiver API-Kandidat ohne importierte Legacy-Rechnung.
  • blocked: inaktiver API-Kandidat oder letzte Rechnung nicht bezahlt.

Report-Command

php artisan api:legacy-customers-report
php artisan api:legacy-customers-report --classification=eligible
php artisan api:legacy-customers-report --portal=businessportal24
php artisan api:legacy-customers-report --no-report

Der Command schreibt standardmäßig:

storage/app/private/migration/legacy-api-customers-*.json

Der Report enthält:

  • Kandidatenregel und bekannte Datenlücken
  • Zusammenfassung nach eligible, needs_review, blocked
  • User-ID, E-Mail, Portal, Legacy-ID
  • Rollen und Registration-Type
  • letzte Legacy-Rechnung inkl. Status, Datum, Betrag
  • empfohlene Aktion:
    • invite_to_generate_sanctum_token
    • manual_billing_review_required
    • do_not_grant_api_access

Aktuelle Datenlage

In der migrierten Datenbank wurden bisher gefunden:

  • 195 User mit registration_type = apiuser
  • 1 API-User mit archivierter Legacy-Rechnung
  • diese Rechnung ist bezahlt

Damit ist nach aktueller Datenlage nur ein API-User automatisch freigabefähig. Die übrigen API-User müssen entweder manuell geprüft werden oder benötigen zusätzliche Legacy-Billing-/Vertragsdaten.

Noch fehlende Daten

Für eine harte finale Entscheidung fehlen ggf.:

  • vollständige Legacy-Zuordnung von API-Usern zu zahlenden Vertrags-/Billing-Usern, falls API-User nicht selbst Rechnungsempfänger waren
  • explizite Legacy-Credential-Zuordnung apiReadAccess / apiWriteAccess pro User, falls feiner als apiuser/api-only benötigt
  • aktuelle fachliche Liste aktiver API-Kunden vom Auftraggeber, falls Rechnungsarchiv nicht ausreicht

Ohne diese Daten ist die sichere Standardeinstellung:

  • nur eligible automatisch zur Token-Migration einladen
  • needs_review nicht automatisch freischalten
  • blocked nicht freischalten

Token-Erstellung im neuen System

Die Customer-Seite für API-Tokens ist zusätzlich technisch abgesichert. Ein User kann nur dann einen Sanctum-Token erstellen, wenn:

  1. users.is_active = true
  2. mindestens eine der folgenden Bedingungen erfüllt ist:
    • aktiver neuer Zahlungsstatus in user_payment_options (status = active, aktueller Zeitraum gültig)
    • aktiver Bestandsschutz in user_payment_options (status = grandfathered, grandfathered_until >= today)
    • Übergangsweise: letzte importierte Legacy-Rechnung ist paid

Damit bekommen reaktivierte oder neue Kunden künftig keinen API-Zugang über alte Rechnungen, sondern erst über die neue aktive Zahlungs-/Vertragslogik. Bereits erstellte Tokens inaktiver User werden zusätzlich bei API-Requests blockiert.

API-Usage-Logging

Neue API-Requests werden persistent in api_usage_logs protokolliert:

  • user_id
  • personal_access_token_id
  • HTTP-Methode
  • Pfad
  • Route-Name
  • Statuscode
  • IP-Adresse
  • User-Agent
  • Dauer in Millisekunden
  • Zeitpunkt

Nicht gespeichert werden:

  • Bearer-Token im Klartext
  • Legacy-api_key
  • Request-Payloads

Auch abgewiesene Legacy-Key-Requests (410 Gone) und Requests inaktiver User (403) werden geloggt.

API-Rate-Limiting

Die /api/v1-Routen sind zusätzlich per Middleware EnsureApiTokenRateLimit limitiert:

  • Limit: 60 Requests pro Minute
  • bevorzugter Schlüssel: Sanctum-/Bearer-Token-ID
  • Fallback: SHA-256-Fingerprint des Bearer-Tokens, danach User-ID/IP
  • inaktive User werden vorher per EnsureApiUserIsActive blockiert
  • überschrittene Limits liefern HTTP 429 mit Retry-After, X-RateLimit-Limit und X-RateLimit-Remaining

Damit wird ein einzelner stark nutzender Client begrenzt, ohne andere Tokens desselben Users sofort mitzusperren.

API-Usage-Reporting

Die protokollierten API-Requests können per Artisan-Command ausgewertet werden:

php artisan api:usage-report
php artisan api:usage-report --from=2026-04-01 --to=2026-04-30
php artisan api:usage-report --user=123
php artisan api:usage-report --status=403
php artisan api:usage-report --no-report

Der Command schreibt standardmäßig:

storage/app/private/migration/api-usage-*.json

Der Report enthält:

  • Gesamtzahl Requests
  • eindeutige User und Sanctum-Tokens
  • 2xx-/4xx-/5xx-Verteilung
  • durchschnittliche Dauer
  • Top-Pfade
  • Statuscode-Verteilung
  • Top-User und Top-Tokens
  • letzte Requests im gefilterten Zeitraum

Damit ist die neue API-Nutzung ab Cutover nicht mehr von Webserver-Logs abhängig und kann regelmäßig exportiert oder später in eine Admin-UI übernommen werden.

P7-Abgrenzung Newsletter

newsletter/unsubscribe wird bewusst nicht als Legacy-API-Endpoint umgesetzt. Es gibt dafür keinen relevanten Legacy-API-Client. Newsletter-Abmeldung und externer Newsletter-Dienst werden nach der Migration im neuen Frontend sauber neu implementiert.