好的,所以我正在尝试在Intranet上使用Laravel实现ACL,并且我遇到了一些问题,即权限迅速失控。首先,这就是我所拥有的:
我的五个表定义了我的用户,我的角色和我的权限,如下所示:
tblIntranetUser
UserID
Name
FirstName
Username
tblIntranetRoles
RoleID
RoleName
Description
tblIntranetPermissions
PermissionID
PermissionName
Description
tblIntranetRoles_Permissions
RoleID
PermissionID
tblIntranetUsers_Roles
UserID
RoleID
我还有AuthServiceProvider以及权限和角色模型:
class Permission extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'tblIntranetPermissions';
protected $primaryKey = 'PermissionID';
public $timestamps = false;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['PermissionID', 'PermissionName', 'Description'];
public function roles()
{
return $this->belongsToMany('App\Role', 'tblIntranetRoles_Permissions', 'PermissionID', 'RoleID');
}
public function detachAllRoles()
{
$roles = $this->roles;
foreach($roles as $role){
$role->permissions()->detach($this);
}
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\User;
class Role extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'tblIntranetRoles';
protected $primaryKey = 'RoleID';
public $timestamps = false;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['RoleID', 'RoleName', 'Description'];
public function permissions()
{
return $this->belongsToMany('App\Permission', 'tblIntranetRoles_Permissions', 'RoleID', 'PermissionID');
}
public function givePermissionTo(Permission $permission)
{
return $this->permissions()->save($permission);
}
public function getUsers()
{
$users = User::orderBy('UserID')->get();
$roleusers = collect();
foreach($users as $user){
if($user->hasRole($this->name)){
$roleusers->push($user);
}
}
return $roleusers;
}
public function detachAllUsers()
{
$users = $this->getUsers();
foreach($users as $user){
$user->roles()->detach($this);
}
}
public function detachAllPermissions()
{
$permissions = $this->permissions;
foreach($permissions as $permission){
$permission->roles()->detach($this);
}
}
}
namespace App\Providers;
use App\Report, App\Permission;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
];
/**
* Register any application authentication / authorization services.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
foreach ($this->getPermissions() as $permission){
$gate->before(function ($user) {
if ($user->isSuperAdmin()) {
return true;
}
});
$gate->define($permission->name, function($user) use ($permission){
return $user->hasRole($permission->roles);
});
}
}
protected function getPermissions()
{
return Permission::with('roles')->get();
}
}
因此,由于这个原因,我能够创建各种角色并为其分配权限,这允许他们访问Intranet的某些部分以及查看某些报告。例如,我可以定义以下内容:
Role: Analyst
Access: Section 1, 2, 3
Reports: 1,15,41
Role: Developer
Access: All sections
Reports: All reports
如果每个分析师都可以看到并访问相同的部分,那就好了......但当然情况并非如此。开发人员也是如此。遵循这个模型,它基本上意味着我需要为每个用户提供一个角色,并为Intranet上的每个可能元素提供一个权限。鉴于有大约200个可用报告以及大约30个用户,这会产生大量“show_report_1”,“show_report_2”,“show_section_1”,“show_section_2”权限(Laravel按名称标识权限)。
所以,为了让事情变得有点......有条不紊地我想,我一直在想是否有办法让一个名为“show_report”的权限与reportID存储在另一个字段中并且避免每个用户有一个角色。
答案 0 :(得分:0)
我不确定执行此操作的“正确”方法,但您可以在其中一个数据透视表(可能是role_permission)中添加一行,并使用该行存储有关该权限的更多特定数据。 (例如,他们可以访问的部分)
点击此处查看透视值:https://laravel.com/docs/5.5/eloquent-relationships#many-to-many
$role = App\Role::find(1);
foreach ($role->permissions as $permission) {
echo $permission->pivot->permission_settings; // [1,2,3]
}
这样你就可以拥有“access_section”的单一权限,然后只需检查数据透视,看看他们可以访问哪些部分。
(尽管可能有更好或“恰当”的方法)