Middleware in Laravel 11 and how to customize them

Middleware in Laravel 11 and how to customize them

Modified
Mar 21, 2024
Written by
Benjamin Crozat
5
comments
4 minutes
read

Introduction to middleware customization in Laravel 11

Starting from Laravel 11, new projects get to experience a slimmer skeleton. Parts of the efforts to make it happen were to remove the default middleware classes.

But how do you customize them then? Easy! Just go into your bootstrap/app.php file and configure them however you want. Let me show you in more detail for the most common use cases.

Customize the most common middleware

Change where guests are redirected

To customize where guests are redirected, use the redirectGuestsTo() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->redirectGuestsTo('/admin/login');
})

Previously, this was happening in the Authenticated.php middleware file.

Change where users and guests are redirected

To customize where users and guests are redirected, use the redirectTo() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->redirectTo(
        guests: '/admin/login',
        users: '/dashboard'
    );
})

Previously, this was happening in the Authenticated.php and RedirectIfAuthenticated.php middleware files.

Exclude cookies from being encrypted

To customize which cookies must not be encrypted, use the encryptCookies() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->encryptCookies(except: [
        'foo',
        'bar',
    ]);
})

Previously, this was happening in the EncryptCookies.php middleware file.

Exclude routes from CSRF protection

To customize which routes must be excluded from CSRF protection, use the validateCsrfTokens() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        '/foo/*',
        '/bar',
    ]);
})

Previously, this was happening in the VerifyCsrfToken.php middleware file.

Exclude routes from URL signature validation

To exclude routes from URL signature validation, use the validateSignatures() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->validateSignatures(except: [
        '/api/*',
    ]);
})

Previously, this was happening in the ValidateSignature.php middleware file.

Prevent converting empty strings in requests

To configure the middleware that converts empty strings to null, use the convertEmptyStringsToNull() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->convertEmptyStringsToNull(except: [
        fn ($request) => $request->path() === 'foo/bar',
    ]);
})

Previously, you had to remove the ConvertEmptyStringsToNull middleware in the app/Http/Kernel.php file or do it on a per route basis.

Prevent string trimming in requests

To configure the middleware responsible for trimming strings, use the trimStrings() method in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trimStrings(except: [
        '/foo',
    ]);
})

Previously, this was happening in the TrimStrings.php middleware file.

Advanced middleware customization

In addition to the basic customizations we’ve covered, Laravel 11 offers more advanced options for middleware manipulation. These can be particularly useful for complex applications or when you need fine-grained control over your middleware stack.

Manipulating the global middleware stack

You can add, remove, or replace middleware in the global stack:

->withMiddleware(function (Middleware $middleware) {
    $middleware->prepend(SomeMiddleware::class);
    $middleware->append(AnotherMiddleware::class);
    $middleware->remove(UnwantedMiddleware::class);
    $middleware->replace(OldMiddleware::class, NewMiddleware::class);
})

Working with middleware groups

Laravel allows you to define and modify middleware groups:

->withMiddleware(function (Middleware $middleware) {
    $middleware->group('custom', [
        FirstMiddleware::class,
        SecondMiddleware::class,
    ]);
    
    $middleware->prependToGroup('web', NewWebMiddleware::class);
    $middleware->appendToGroup('api', NewApiMiddleware::class);
    $middleware->removeFromGroup('web', OldWebMiddleware::class);
    $middleware->replaceInGroup('api', OldApiMiddleware::class, NewApiMiddleware::class);
})

API-specific configurations

For API-focused applications, Laravel provides specific methods:

->withMiddleware(function (Middleware $middleware) {
    $middleware->statefulApi(); // Enable Sanctum's frontend state middleware
    $middleware->throttleApi('custom_limiter', true); // Configure API rate limiting
})

Configuring trusted proxies and hosts

For applications behind a proxy or load balancer:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustHosts(['example.com', '*.example.com']);
    $middleware->trustProxies(['192.168.1.1', '192.168.1.2']);
})

Enabling authenticated sessions

To ensure sessions are authenticated in the “web” middleware group:

->withMiddleware(function (Middleware $middleware) {
    $middleware->authenticateSessions();
})

These advanced options provide more flexibility in customizing your application’s middleware behavior, allowing you to fine-tune security, performance, and functionality as needed.

About Benjamin Crozat
Benjamin Crozat

Hi! I’m from the South of France and I’ve been a self-taught web developer since 2006. When I started learning PHP and JavaScript, PHP 4 was still widely used, Internet Explorer 6 ruled the world, and we used DHTML to add falling snow on websites.

Being able to educate myself for free on the web changed my life for the better. Giving back to the community was a natural direction in my career and I truly enjoy it.

Therefore, I decided to take action:

  1. I launched this blog in September 2022 with the goal to be in everyone’s Google search. I get more than tens of thousands of monthly clicks from it and even more visits overall (my analytics dashboard is public by the way).
  2. I also started growing my X (formerly Twitter) account at the same time, which has now over 7,000 followers.
  3. All the content I write is free thanks to my sponsors.

I also want to be completely free with my time and make a living with my own products. In April 2024, I launched Nobinge, a tool to summarize and chat with your content, including YouTube videos.

Believe me, I’m just getting started!

5 comments

Drew Bertola
Drew Bertola 1 year ago
$middleware->convertEmptyStringsToNull(except: [
    fn ($request) => $request->path() === 'foo/bar',
]);

Didn’t work for me. I tried this and it worked:

$middleware->api()->remove(ConvertEmptyStringsToNull::class);
Drew Bertola
Drew Bertola 1 year ago

So, that just removes it from routes under /api/. I suppose you could remove it globally as well. BTW, thanks!

Benjamin Crozat

Great tip I didn’t know, thanks a lot Drew!

mariano-bruno
mariano-bruno 10 months ago

Gracias amigo, me fui muy util la informacion de las cookies. Saludos desde Argentina

Benjamin Crozat
Benjamin Crozat 10 months ago

You’re welcome!

You need to be signed in to comment this post.
Sign in with GitHub