Все статьи
POST вебхука Laravel обходит CSRF через VerifyCsrfToken except, байты getContent проверяются hash_equals на локальном php artisan serve.
LaravelPHPwebhook debugginglocal testing

Вебхуки Laravel: исключение CSRF, сырой body и проверка подписи

Laravel включает CSRF на каждом web-маршруте. Провайдеры вебхуков шлют POST без cookie сессии и CSRF-токена — вы получаете 419 до контроллера. Решение: точечное исключение CSRF и сырой body через $request->getContent().

Исключить webhook-маршруты из CSRF

Добавьте URI в массив $except в App\Http\Middleware\VerifyCsrfToken (Laravel 11+: middleware в bootstrap/app.php):

protected $except = [
    'webhooks/stripe',
    'webhooks/*',
];

Исключайте только server-to-server пути — не отключайте CSRF глобально.

Читать сырой body для проверки подписи

После обхода CSRF читайте нетронутые байты:

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);
}

Используйте getContent(), не all() или input() — хелперы Laravel не дают подписанные байты.

Проверять подпись до бизнес-логики

Извлеките заголовки, вычислите digest из сырого payload и сравните через hash_equals. При ошибке — 401. См. руководство по проверке подписи.

Настроить туннель

  1. Запустите Laravel: php artisan serve --port=8000.
  2. Второй терминал: npx portpreview 8000.
  3. Вставьте URL туннеля + путь в dashboard провайдера.
  4. С TrustProxies доверяйте forwarded-заголовкам туннеля.
  5. Отправьте тестовое событие.

Типичные ловушки

Двойное чтение body

getContent() после json() пуст. Читайте один раз, проверяйте, парсите.

Порядок middleware

Глобальный JSON-парсер до контроллера меняет байты. Изолируйте webhook-маршруты.

Повторы и идемпотентность

Сохраняйте ID событий — см. паттерны повторов и идемпотентности.

Дальше

Основы — в основах туннелирования localhost и практической локальной отладке вебхуков. Механика подписей — в руководстве по проверке подписи. Безопасные от повторов обработчики — в паттернах повторов и идемпотентности. начните PortPreview бесплатно.

Часто задаваемые вопросы

Почему Laravel возвращает 419 на webhook POST?
VerifyCsrfToken отклоняет POST без CSRF-токена. Добавьте путь webhook в $except и проверяйте подпись.
getContent() или all() для вебхуков?
Используйте getContent() для проверки подписи. all() и input() возвращают разобранные данные, а не подписанные байты.
Как тестировать Laravel вебхуки локально?
Запустите php artisan serve, откройте через npx portpreview, вставьте URL туннеля в dashboard и отправьте тестовые события.