Laravel protege cada ruta web con CSRF. Los proveedores webhook envían POST sin cookie de sesión ni token CSRF — obtienes 419 antes de que ejecute el controlador. Solución: exención CSRF dirigida y cuerpo crudo con $request->getContent().
Eximir rutas webhook del CSRF
Añade la URI al array $except en App\Http\Middleware\VerifyCsrfToken (Laravel 11+: middleware en bootstrap/app.php):
protected $except = [
'webhooks/stripe',
'webhooks/*',
];
Limita las exenciones a rutas server-to-server — nunca desactives CSRF en toda la app.
Leer el cuerpo crudo para verificar firmas
Tras sortear CSRF, lee bytes intactos:
public function handle(Request $request)
{
$payload = $request->getContent(); // raw string
$signature = $request->header('Stripe-Signature', '');
if (!$this->verifySignature($payload, $signature)) {
return response('', 401);
}
$event = json_decode($payload, true, 512, JSON_THROW_ON_ERROR);
$this->processEvent($event);
return response('', 200);
}
Usa getContent(), no all() ni input() — los helpers de Laravel no devuelven los bytes firmados.
Verificar firmas antes de la lógica de negocio
Extrae cabeceras, calcula el digest del payload crudo y compara con hash_equals. Devuelve 401 si falla. Ver guía de verificación de firmas.
Configurar el túnel
- Inicia Laravel:
php artisan serve --port=8000. - Segundo terminal:
npx portpreview 8000. - Pega URL del túnel + ruta en el dashboard.
- Con
TrustProxies, confía en headers forwarded del túnel. - Dispara un evento de prueba.
Trampas comunes
Leer el cuerpo dos veces
getContent() tras json() devuelve vacío. Lee una vez, verifica, parsea.
Orden del middleware
Middleware global que parsea JSON antes del controlador altera bytes. Aísla rutas webhook.
Reintentos e idempotencia
Persiste IDs de evento — ver patrones de reintentos e idempotencia.
Para profundizar
Para los fundamentos, lea los fundamentos del tunneling localhost y depuración práctica de webhooks en local. Para la criptografía, consulte la guía de verificación de firmas. Para handlers sin duplicados, lea patrones de reintentos e idempotencia. empiece PortPreview gratis.
