【问题标题】:How can I add OR relationship in laravel middleware for a Route如何在 laravel 中间件中为 Route 添加 OR 关系
【发布时间】:2021-10-17 17:40:24
【问题描述】:

我正在使用 spatie/laravel-permission 为我的路线添加权限。

我拥有的一条路线可以通过两个权限访问(earningsfinancial_fund)。用户无需同时拥有这两种权限即可访问控制器。他可以通过拥有其中一个权限或同时拥有这两个权限来访问控制器。

我试过写这样的东西。

Route::group(['middleware' => ['can:earnings']], function () {
    Route::get('/payment', [PaymentsController::class, 'getAll']);
    Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});
Route::group(['middleware' => ['can:financial_fund']], function () {
    Route::get('/payment', [PaymentsController::class, 'getAll']);
    Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});

但是上面的代码只允许拥有can:earnings权限的用户访问路由,不允许拥有can:financial_fund权限的用户。

我也试过写这样的东西

Route::group(['middleware' => ['can:earnings,financial_fund']], function () {
    Route::get('/payment', [PaymentsController::class, 'getAll']);
    Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});

但这需要当前用户同时存在这两个权限。

我怎么知道我只希望至少存在一个权限?

我发现 Laravel 引入了 canAny 用于刀片模板。有没有办法在定义路由时在我的 api.php 文件中使用它?

【问题讨论】:

  • 只需使用 OR 运算符。['can:earnings|financial_fund'].Routes 总是从上到下执行。因此,一旦它收到相关路由,它就不会进一步执行。

标签: laravel routes laravel-permission


【解决方案1】:

我通过创建一个新的中间件来修复它

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class AuthorizeCanAny
{
    public function handle(Request $request, Closure $next, ...$permissions)
    {
        if (!$request->user()) {
            abort(403);
        }

        $userPermissions = array_map(function ($e) {
            return $e['name'];
        }, $request->user()->permissions->toArray());

        $userPermissionsIntersect = array_intersect($userPermissions, $permissions);

        if (!sizeof($userPermissionsIntersect)) {
            abort(403);
        }

        return $next($request);
    }
}

将中间件添加到 kernal.php 文件中

protected $routeMiddleware = [
    ...,
    'canAny' => AuthorizeCanAny::class,
];

然后在路由器中使用

Route::group(['middleware' => ['canAny:earnings,financial_fund']], function () {
    Route::get('/payment', [PaymentsController::class, 'getAll']);
    Route::post('/payment/cash', [PaymentsController::class, 'addCashPayment']);
});

【讨论】:

    猜你喜欢
    • 2012-12-07
    • 2015-11-25
    • 1970-01-01
    • 2018-12-30
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多