rap-2-h
rap-2-h

Reputation: 32078

Enable global middleware only for one environment in Laravel 5

I'm using a global middleware in Laravel 5 (barryvdh/laravel-cors) but I only want it to be active on one environnement (dev). That's because I only require it with composer in dev environnement, so it's not installed in production.

I registered it has a global middleware in App Kernel and so I have an error if I try to deploy my app in production (Class 'Barryvdh\Cors\CorsServiceProvider' not found). I know why, but I'm looking for a solution.

Is there any way to declare a middleware globally in laravel 5 but only required in one environnement ?

I hope it's clear enough, I can edit my post if not :)

Upvotes: 13

Views: 8247

Answers (6)

user17789225
user17789225

Reputation: 11

I am new to SO so I am not allowed to comment other answers. I know this is an old topic but thanks to search you still find it.

In the accepted answer a user asked:

When I try this in app/Http/Kernel.php I get ( ! ) Fatal error: Uncaught exception 'ReflectionException' with message 'Class App\Http\Application does not exist' in /home/vagrant/earthport/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 836

I also had this issue and basically you just need to make sure to include the classes

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Routing\Router;

Upvotes: 1

JasonJensenDev
JasonJensenDev

Reputation: 2407

I know I'm a little late to the party, but I wanted to contribute something that I learned while researching this very same question. I was trying to apply Spatie's Response Cache package only if debug mode was turned off (so that while I was developing, I wouldn't have to constantly clear the cache to see updates). I wanted to apply the \Spatie\ResponseCache\Middlewares\CacheResponse middleware to the web middleware group. In order to do this, I followed the advice of @ralphowino, but made the following changes:

AppServiceProvider.php

<?php

namespace App\Providers;

use App\Http\Kernel;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(Kernel $kernel)
    {
        if (!env('APP_DEBUG')) {
            $kernel->appendMiddlewareToGroup('web', '\Spatie\ResponseCache\Middlewares\CacheResponse');
        }
    }
}

Hope this helps somebody.

P.S. I realize that there are many ways to accomplish the objective I explained above such as customizing the Spatie Cache Profile as found in the docs. I just think this is a bit cleaner.

Upvotes: 0

ralphowino
ralphowino

Reputation: 539

To achieve this simply load kernel in the service provider then call either pushMiddleware or prependMiddleware

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot(Kernel $kernel)
    {
        if ($this->app->environment() === 'dev') {
            $kernel->prependMiddleware(ClockworkMiddleware::class);
        }
    }
}

Upvotes: 9

murph
murph

Reputation: 147

I had the opposite query to yours - wanting to implement middleware globally in production but not in local development. I tried the __construct() method EspadaV8 recommended but it did work for me as env('APP_ENV') failed to return a value that I could test.

What I did instead was to include my middleware in the Kernel $middleware array and then, in the handle($request, Closure $next) method in my middleware, I bracketed all of my code - except return $next($request); - with the following:

if(env('APP_ENV') !== 'local') { 

.......middleware code.......

}

Perhaps the opposite would work for you (i.e. === instead of !==)?

I suspect this is not the best solution - as you point out, it would be ideal to handle the loading of the middleware (or not) in the Kernel class but in lieu of finding something better as of yet, I thought to put this solution out there. Hope it helps!

Upvotes: 0

EspadaV8
EspadaV8

Reputation: 668

The best way I've found so far is to check env('APP_ENV') in the Kernel

public function __construct(Application $app, Router $router)
{
    if (env('APP_ENV', 'production') === 'local') {
        $this->prependMiddleware('Clockwork\Support\Laravel\ClockworkMiddleware');
    }

    parent::__construct($app, $router);
}

Upvotes: 1

Helder Lucas
Helder Lucas

Reputation: 3353

In the kernel.php file

 //...
 protected middleware = [
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'App\Http\Middleware\VerifyCsrfToken',
    (!$this->app->environment('local')) ?: 'Path/To/Package'
 ]

This should solve.

Upvotes: 1

Related Questions