首页 > 解决方案 > 允许根据设置的权限以及模型在 Laravel 中的属性值编辑模型

问题描述

我有一个位置模型,其中包含两个属性:ID 和名称。

为了编辑这个模型,我设置了这条路线:

Route::get('administration/location/{location}/edit', 'LocationController@edit')->name('location.edit');

我设置了非常简单的权限:在AuthServiceProvider我正在检查boot以下方法中

Gate::before(function ($user, $permission) {
    if ($user->permissions->pluck('name')->contains($permission)) {
        return true;
    }
});

permission包含 ID 和名称的模型在哪里,通过permission_user表映射。

我设置了以下权限:

在所有这些杂乱无章之后,我的实际问题是:

如何将这些权限与编辑位置联系起来?

我面临的问题是,不允许给定用户编辑所有位置,但可能只允许编辑一个位置。只有具有权限的用户edit_los_angeles才能Location使用 name进行编辑Los Angeles
因此,我无法将其分组为一个权限,例如edit_location并将其添加到我的路线->middleware('can:edit_location')中。

相反,我想我需要这样的东西:

Route::get('administration/location/{location}/edit', 'LocationController@edit')->name('location.edit')->middleware('can:edit_los_angeles');
Route::get('administration/location/{location}/edit', 'LocationController@edit')->name('location.edit')->middleware('can:edit_new_york');
Route::get('administration/location/{location}/edit', 'LocationController@edit')->name('location.edit')->middleware('can:edit_boston');

...显然这行不通。

解决这个困境的方法是什么?:-)
也许我做错了什么,有更好的 Laravel-Way 这样做吗?

非常感谢您提前提供的帮助!

我正在使用 Laravel 6.0 :-)

标签: phplaravellaravel-6

解决方案


如果您有基于位置关系的要求,那么您将需要在数据中捕获该关系。一个很好的起点是添加特定于这些编辑权限的数据透视表。考虑一个location_permissions带有 auser_id和 a的表location_id。然后,您可以修改或添加权限中间件,以便在您拥有特定用户和位置后检查此表中的记录。

编辑:回答关于中间件实现的问题,

通过这个新的数据透视表定义用户模型与位置的关系可能会解决实现的关键。

我建议然后添加一个附加方法,该方法使用locations与模型的新关系

public function canEditLocation(Location $location): bool { 

   return $this->locations
               ->where('location_id', '=', $location->id)
               ->count() > 0; 
    }

实际的中间件是这样的:

public function handle($request, Closure $next, $location)
    {
        if (! $request->user()->canEditLocation($location)) {
            \\handle failed permission as appropriate here.
        }

        return $next($request);
    }

我的中间件参数知识很生疏,但我相信这是正确的,如https://laravel.com/docs/master/middleware#middleware-parameters所定义


推荐阅读