Uebernahme bestehender Legacy-API-Integrationen (Keys, Auth, Pfade)

Bestehende Kunden-Integrationen der Altportale laufen nach dem Relaunch
weiter, ohne dass Kunden etwas umstellen muessen:

1. legacy:import-api-keys uebernimmt die api_keys aus den Legacy-DBs
   (sf_guard_user_profile) als Sanctum-Tokens mit identischem Secret
   (Sanctum loest Tokens ohne id|-Praefix per sha256-Hash auf) — nur
   fuer berechtigte Nutzer (aktiver Zahlungsstatus/Bestandsschutz,
   ApiAccessEligibilityService); idempotent, mit Dry-Run. Probe gegen
   die lokalen Snapshots: 406 Keys wuerden uebernommen.
2. Die Auth-Middleware uebersetzt die alten Uebergabeformen (X-ApiKey-
   Header, api_key-Parameter) fuer gueltige Keys in Bearer; unbekannte
   Keys erhalten weiterhin 410 mit Migrationshinweis.
3. Die dokumentierten /service/...-Pfade der Alt-API sind als Aliasse
   auf die v1-Controller gelegt (pressreleases inkl. Bilder, companies
   lesend); nicht uebernommene Alt-Endpoints (Pressemappen/Kontakte
   anlegen) antworten 410 mit Hinweis auf Kundenkonto und neue Doku.

API-Seite + OpenAPI entsprechend aktualisiert; Go-Live-Checkliste um den
Import-Schritt (nach dem Grandfathering) ergaenzt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-06 11:55:22 +00:00
parent 3364fd13b8
commit 616b7847d4
11 changed files with 425 additions and 13 deletions

View file

@ -4,8 +4,17 @@ namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Laravel\Sanctum\PersonalAccessToken;
use Symfony\Component\HttpFoundation\Response;
/**
* Legacy-API-Kompatibilität (Übernahme bestehender Integrationen,
* 06.07.2026): Die Altportale authentifizierten per `X-ApiKey`-Header bzw.
* `api_key`-Parameter. Importierte Legacy-Keys (legacy:import-api-keys)
* sind gültige Sanctum-Tokens — hier wird die alte Übergabeform in einen
* Bearer-Header übersetzt, damit `auth:sanctum` sie versteht. Unbekannte
* Keys erhalten weiterhin 410 mit Migrationshinweis.
*/
class RejectLegacyApiKeys
{
/**
@ -15,14 +24,44 @@ class RejectLegacyApiKeys
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->has('api_key') || filled($request->header('X-Api-Key'))) {
return response()->json([
'message' => 'Legacy API keys are no longer supported.',
'migration_url' => url('/customer/tokens'),
'docs_url' => url('/docs/api/v1'),
], 410);
$legacyKey = $this->legacyKey($request);
if ($legacyKey === null) {
return $next($request);
}
return $next($request);
// Ein explizit gesetzter Bearer-Token hat Vorrang.
if (filled($request->bearerToken())) {
return $next($request);
}
if (PersonalAccessToken::findToken($legacyKey) !== null) {
$request->headers->set('Authorization', 'Bearer '.$legacyKey);
return $next($request);
}
return response()->json([
'message' => 'This API key is not valid (anymore). Please generate a token in your customer account.',
'migration_url' => url('/customer/tokens'),
'docs_url' => url('/docs/api/v1'),
], 410);
}
/**
* Legacy-Schlüssel aus den historischen Übergabeformen: `X-ApiKey`
* (dokumentierter Header der Altportale), `X-Api-Key` (verbreitete
* Schreibvariante) oder `api_key` als Query-/Body-Parameter.
*/
private function legacyKey(Request $request): ?string
{
$key = trim((string) (
$request->header('X-ApiKey')
?: $request->header('X-Api-Key')
?: $request->query('api_key')
?: $request->input('api_key')
));
return $key === '' ? null : $key;
}
}