用于资源路由的单个中间件?

时间:2018-10-03 21:43:49

标签: php laravel

我希望每个单独的路由都有一个不同的中间件,就像可以使用名称一样。例如

Route::resource('posts', 'PostsController', [
    'names' => [
        'index' => 'custom-index-name',
        'store' => 'custom-store-name'
    ]
]);

但是我想使用中间件来实现,但这似乎是不可能的。有办法吗?

3 个答案:

答案 0 :(得分:1)

https://laravel.com/docs/5.7/controllers#controller-middleware

这表示您可以使用$this->middleware(...)->only('...');将中间件限制为控制器方法,这种方法应允许您仍然使用Route::resource(...)

答案 1 :(得分:0)

您可以按以下步骤按路线外观进行操作:分别为每个动作创建应用的单独路线

 Route::post('/add','userController@add')->middleware('addMiddleware');
 Route::post('/edit','userController@edit')->middleware('editMiddleware');

您可以添加多个中间件

Route::post('/delete','userController@delete')->middleware([addMiddleware::class,editMiddleware::class]);

有关更多信息,请参见middleware

答案 2 :(得分:0)

Laravel 不支持路由器资源上的每个动作的中间件 我的解决方案:覆盖路线 Illuminate\Routing\Route@middleware

第 1 步:创建我的路由并覆盖中间件:app/Services/Helpers/Route.php

namespace App\Services\Helpers;

use Illuminate\Routing\Route as RoutingRoute;

class Route extends RoutingRoute
{
    /**
     * Get or set the middlewares attached to the route.
     *
     * @param  array|string|null  $middleware
     * @return $this|array
     */
    public function middleware($middleware = null)
    {
        $this->filterMiddleware();

        return parent::middleware($middleware);
    }

    /**
     * Assign permission middleware only for action of route resource
     *
     * @return void
     */
    private function filterMiddleware()
    {
        $controller = $this->action['controller'] ?? null;
        if (!$controller || !is_string($controller)) {
            return;
        }

        $action = explode('@', $this->action['controller'])[1] ?? null;
        if (!$action || !is_string($action)) {
            return;
        }

        // Illuminate\Routing\ResourceRegistrar::$resourceDefaults
        $acceptActions = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy'];

        foreach ($this->action['middleware'] as $key => $middleware) {
            if (is_string($key) && in_array($key, $acceptActions) && $action !== $key) {
                unset($this->action['middleware'][$key]);
            }
        }
    }
}

第 2 步:创建我的路由器:app/Services/Router.php

namespace App\Services;

use App\Services\Helpers\Route;
use Illuminate\Routing\Router as RoutingRouter;

class Router extends RoutingRouter
{
    /**
     * Create a new Route object.
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  mixed  $action
     * @return \App\Http\Controllers\Admin\Route
     */
    public function newRoute($methods, $uri, $action)
    {
        return (new Route($methods, $uri, $action))
            ->setRouter($this)
            ->setContainer($this->container);
    }
}

第 3 步:添加到 bootstrap/app.php 以重新创建路由器单例:

// custom router for this project
$app->singleton('router', App\Services\Router::class);

第 4 步:在我的 routes/admin.php 上使用

// Role
Route::resource('roles', 'RoleController')
    ->only(['index', 'show', 'store', 'update', 'destroy'])
    ->middleware([
        'index' => 'permission:roles.show',
        'show' => 'permission:roles.show',
        'store' => 'permission:roles.create',
        'update' => 'permission:roles.update',
        'destroy' => 'permission:roles.delete',
    ]);