NestJS-Webhook-Handler scheitern subtil. Ein globaler ValidationPipe entfernt Felder vor dem Guard, und Standard-JSON-Parsing zerstört die signierten Bytes. Lokales Testen soll rawBody: true, Signatur-Guards und route-spezifische Validierung beweisen, bevor du eine Tunnel-URL bei Stripe oder GitHub einträgst.
Raw Body beim Bootstrap aktivieren
Übergib rawBody: true bei NestFactory.create, damit Express einen unveränderten Buffer behält:
async function bootstrap() {
const app = await NestFactory.create(AppModule, { rawBody: true });
app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
await app.listen(3000);
}
Ohne dieses Flag ist req.rawBody undefined und jeder HMAC-Check scheitert.
@Body() vs req.rawBody für Signaturen
Signiere niemals gegen @Body() — Nest hat das Objekt bereits geparst. Lies den Buffer vom raw-body-Middleware:
@Post('stripe')
@UseGuards(StripeSignatureGuard)
handleStripe(@Req() req: RawBodyRequest) {
const payload = req.rawBody;
const event = JSON.parse(payload.toString('utf8'));
this.events.process(event);
return { received: true };
}
Parse JSON erst nach Guard-Bestätigung. Reihenfolge: Guard zuerst, Deserialisierung danach.
Signatur-Guard vor ValidationPipe-Effekten
Kapsle Provider-Verifikation in einem Guard mit Header-Lesen und constant-time-Vergleich:
@Injectable()
export class StripeSignatureGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const req = context.switchToHttp().getRequest>();
const sig = req.headers['stripe-signature'] as string;
return verify(req.rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET);
}
}
Wende den Guard mit @UseGuards nur auf der Webhook-Route an.
Die ValidationPipe-Falle vermeiden
Ein globaler ValidationPipe mit transform: true kann Typen vor dem Controller erzwingen. Webhook-Routen brauchen rawBody + manuelles JSON.parse nach Verifikation.
Lokales Testen mit nest start + PortPreview
- API starten:
npm run start:devodernest start --watchauf Port 3000. - Exponieren:
npx portpreview 3000. - Tunnel-URL + Webhook-Pfad registrieren.
- Test-Lieferungen auslösen.
- Doppelte Event-IDs wiederholen — siehe Retry-Muster.
Häufige Stolperfallen
ValidationPipe vor Signaturprüfung
Läuft Validierung zuerst, kann Nest den Body transformieren und rawBody leer lassen. Guards müssen auf dem Raw-Buffer laufen.
Reihenfolge globales JSON-Middleware
Express json() vor raw-body verbraucht den Stream. rawBody: true bei Factory-Erstellung beibehalten.
Langsame Handler und Retries
Nach Verifikation schnell 200 zurückgeben, schwere Arbeit queuen, per Event-ID deduplizieren.
Weiterführend
Grundlagen finden Sie unter localhost-Tunneling-Grundlagen und praktisches lokales Webhook-Debugging. Zur Signaturmechanik siehe den Leitfaden zur Signaturprüfung. Für duplikatsichere Handler lesen Sie Retry- und Idempotenz-Muster. starten Sie PortPreview kostenlos.
