Zum Inhalt springen

Aufgabe 20 - Der Türsteher

Zu Zen-Modus wechseln

Middleware und Schema-Validierung bringen Ihre API auf Produktionsniveau: zentrales Logging, echte Zugriffskontrolle statt des Rollen-Header-Provisoriums, zod-Schemas statt Handprüfungen und ein Fehlerformat, das technisch überall gleich ist. Am Ende steht der Angriffstest durch die Sitznachbarin oder den Sitznachbarn (siehe Kapitel Middleware und Validierung).

  • Kapitel Middleware und Validierung; Ihr Buffet-Projekt nach Aufgabe 19; zod.
  • Sie setzen Middleware für Querschnittsaufgaben (Logging, Zugriffskontrolle) ein.
  • Sie validieren Eingaben mit zod-Schemas und leiten Typen mit z.infer ab.
  • Sie halten ein konsistentes Fehlerformat technisch über die ganze API durch.
  • Reproduktion: Logging-Middleware nach dem Kapitelmuster einrichten (Teil A).
  • Reorganisation und Transfer: Zugriffskontrolle und Schema-Validierung in das bestehende Projekt integrieren (Teile B und C).
  • Reflexion, Problemlösung und Urteilsbildung: die API einem Angriffstest aussetzen und die Ergebnisse bewerten (Teil D).

Die Übung ist auf etwa zwei Stunden ausgelegt. Teil D ist der Expertenteil.

  1. Legen Sie middleware.ts mit Matcher auf /api/:path* an: Jede API-Anfrage wird geloggt (Zeitstempel, Methode, Pfad).
  2. Lesen Sie das Log: Welche Endpunkte ruft ein Aufruf der Verwaltungsseite tatsächlich auf, und wie oft? Überraschungen (doppelte Aufrufe, unerwartete Requests) notieren; das Log ist ab jetzt Ihr Diagnosewerkzeug.
  1. Ersetzen Sie den x-role-Header aus Aufgabe 15: Eine einfache Login-Route (POST /api/login mit einem im Unterricht vereinbarten Kennwort) setzt ein signiertes Cookie; das Geheimnis zum Signieren kommt aus .env.local (in der .gitignore!).
  2. Die Middleware prüft das Cookie und weist Verwaltungsrouten ohne Buffet-Rolle mit 401 (nicht angemeldet) beziehungsweise 403 (falsche Rolle) ab, im Fehlerformat des Vertrags.
  3. Aus den Route Handlers fliegt jede Rollenabfrage heraus; die Prüfung existiert genau einmal. Halten Sie den Diff fest. Dank der Kapselung aus Aufgabe 16 ändert sich im Client nur die eine Hilfsfunktion.
  1. Definieren Sie zod-Schemas für alle Request-Bodies (Bestellung, Artikel, Login) in lib/schemas.ts, inklusive der Regeln aus der Doku (1 bis 5 Positionen, Preis größer 0, Mengen ganzzahlig, …).
  2. Ersetzen Sie die handgeschriebene Formvalidierung durch safeParse; Validierungsfehler antworten mit 400 und feldgenauen details im einheitlichen Fehlerformat. Fachliche Prüfungen (Menge reicht, Bestellschluss) bleiben im Service; ziehen Sie die Grenze bewusst und dokumentieren Sie sie in einem Kommentar.
  3. Leiten Sie die TypeScript-Typen mit z.infer aus den Schemas ab und löschen Sie die dadurch überflüssigen Interface-Duplikate. Notieren Sie im Commit, welches Duplikat verschwunden ist: Vertrag, Prüfung und Typ sind jetzt eine Quelle.
  1. Übergeben Sie Ihre laufende API samt HTTPie an Ihre Sitznachbarin oder Ihren Sitznachbarn: zehn Minuten freies Angreifen. Pflichtprogramm: Bestellung mit 999 Positionen, negativer Preis, String statt Zahl, kaputtes JSON, Verwaltungszugriff ohne Login und mit falscher Rolle, überlanger Artikelname, unbekannte Felder im Body.
  2. Bestehenskriterium: Jede Antwort ist kontrolliert (400/401/403/404/409 im Fehlerformat); kein 500, kein Stack Trace, kein Absturz. Protokoll führen: Angriff, Antwort, bestanden ja/nein.
  3. Jeder nicht bestandene Fall wird behoben und der Angriff wiederholt; das Protokoll dokumentiert beide Durchgänge.
  4. Beurteilen Sie in drei Sätzen: Welche Angriffe hat die Middleware abgefangen, welche das Schema, welche der Service? Passt diese Verteilung zur Architektur, oder ist etwas an der falschen Stelle gelandet?
  1. Warum gehört die Rollenprüfung in die Middleware und nicht in jeden Handler?
  2. Was unterscheidet 401 von 403?
  3. Was leistet safeParse gegenüber parse, und warum passt es besser an die API-Grenze?
  4. Welches Duplikat beseitigt z.infer, und warum ist das mehr als Kosmetik?
  5. Warum darf eine 500-Antwort keine internen Details enthalten?

Git-Repository, der Diff aus Teil B, und das zweistufige Angriffsprotokoll aus Teil D.