如何有条件地在Kernel.php中加载Laravel中间件?

时间:2019-11-02 05:02:24

标签: laravel

我需要为本地环境而不是生产环境加载中间件。 目前,它是在$middleware数组中的app / Http / Kernel.php中定义的。

是否可以检查那里的环境,然后使用三元表达式?还是尚未加载环境变量?使用Laravel 5.8

4 个答案:

答案 0 :(得分:1)

只是,您可以像下面这样在kernel.php中设置中间件组

kernel.php

protected $middlewareGroups = [
        'local' => [
            // \App\Http\Middleware\EncryptCookies::class,
            // \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            // \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            // \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            // \App\Http\Middleware\VerifyCsrfToken::class,
            // \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'dev' => [
            ...
        ],
    ];

RouteServiceProvider.php

现在,您可以在RouteServiceProvider中设置本地中间件。

public function map()
    {
        if ($this->app->environment('local)) {
            Route::middleware('local')
                 ->namespace($this->namespace)
                 ->group(base_path('routes/web.php'));
        }
    }

未测试

答案 1 :(得分:0)

使用服务提供商注册该中间件而不是直接将其放置在$middleware中的全局中间件堆栈app/Http/Kernel.php中怎么办?

您可以在boot方法中让服务提供者根据所需条件向HTTP内核注册中间件:

public function boot()
{
    if ($this->app->environment('local')) {
        $this->app->make(\Illuminate\Contracts\Http\Kernel::class)
            ->pushMiddleware(\Some\Package\Middleware::class);
    }
}

您拥有pushMiddlewareprependMiddleware方法。

答案 2 :(得分:0)

您只需要检查中间件中的环境即可。您无需告诉Laravel仅在本地时加载中间件,而只需要告诉您的代码仅在本地时运行即可。

FooMiddleware.php

class FooMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (app()->environment('local')) {
            // some stuff
        }

        return $next($request);
    }
}

如果中间件不是您的中间件,那么您只需要扩展该中间件或将该中间件链接起来,然后执行上述操作即可。例如,当您只需要在本地运行Illuminate\Auth\Middleware\Authorize时,则:

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authorize as Middleware;

class Authorize
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $ability
     * @param  array|null  ...$models
     * @return mixed
     */
    public function handle($request, Closure $next, $ability, ...$models)
    {
        if (app()->environment('local')) {
            // chain the middleware 
            return app(Middleware::class)->handle($request, function ($request) use ($next) {
                return $next($request);
            }, $ability, $models);
        }

        return $next($request);
    }
}

然后,只需将 Kernel.php 替换为新的中间件。

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    ...
    'can' => \App\Http\Middleware\Authorize::class,
    ...
]

答案 3 :(得分:0)

最后我要保护所有开发或测试服务器。就像魅力一样。

class TestMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
          if(env('APP_ENV') != 'production') {
            f(Request::getUser() != 'test'){
                return Response::make('Invalid credentials.', 401, $headers);
            }
        }

        return $next($request);
    }
}