Laravel 11 - Disable CSRF for a route
Stefan Izdrail
Founder & Senior Architect · 2026-06-29
Dealing with webhook endpoints can present unique challenges, especially when it comes to handling Cross-Site Request Forgery (CSRF) protection. In Laravel 11, the default CSRF verification mechanism has changed, making it necessary for developers to adapt their approaches accordingly. This blog post will guide you through disabling CSRF protection for a specific route in Laravel 11 and address potential issues along the way.
Understanding Cross-Site Request Forgery
Cross-Site Request Forgery (CSRF) is an attack that exploits legitimate users' sessions to execute unwanted actions on websites. It can be dangerous, especially in scenarios where sensitive information or privileged operations are concerned. By default, Laravel 11 provides strong CSRF protection for all routes using the VerifyCsrfToken middleware.
The Problem: Enable Webhooks with No CSRF Verification
In your case, you've identified that a webhook endpoint is failing because HTTP error code 419 is being returned. This error code is specifically used in Laravel to indicate that the request was not able to proceed due to failed CSRF token verification. To ensure successful webhook calls from remote services, we need to disable CSRF protection for a specific route.
The Solution: Disable CSRF Verification Using Route Groups
In Laravel 11, the VerifyCsrfToken middleware is no longer present. However, we can still disable CSRF verification for specific routes using route groups. Follow these steps:
- Create a new route group for webhook endpoints by running the command:
php artisan make:policy WebhookPolicy - Open the newly created policy file and add the
@handlemethod. This method will hold all your route definitions:
```php
In your application's - Adjust the auth middleware to allow access without CSRF verification for this route group: ```php protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\ConvertEmptyStringsToNulls::class, \App\Http\Middleware\VerifyCsrfToken::class, // Disable this line for CSRF-less routes ], ]; ```
- Create a webhook route in the new route group: ```php Route::post('webhook/example', [WebhookController::class, 'handleExampleRequest']); // Define your route as needed ```
- Import the newly created policy for use with the webhook controller class and method calls: ```php namespace App\Http\Controllers; use App\Http\Requests\WebhookRequest; use Illuminate\Routing\Controller; use Illuminate\Support\Facades\Auth; use App\Policies\WebhookPolicy as WebhookPolicy; class WebhookController extends Controller { public function handleExampleRequest(WebhookRequest $request) { if (Auth::user() && Auth::user()->can(WebhookPolicy::class, $routeName)) { // Your webhook request logic goes here } } ```
- Test your new CSRF-less route and ensure that the error code 419 no longer appears.
app/Http/Kernel.php file, modify the $routes property to include the newly created route group:
```php
protected function routes()
{
$this->group(['prefix' => 'api', 'middleware' => ['auth','webhook']], function() {
require_once __DIR__ . '/../Http/routes.php';
require_once __DIR__ . '/../Api/Routes/WebhooksRoute.php'; // Add your webhook routes here
});
```