Laravel 管理基于对象的权限-ACL

问题描述 投票:0回答:1

我对雄辩不是很熟悉。我有两个数据库模式。我已经尝试过使用和不使用 json 字段,但我找不到解决方案来获取:

  1. 登录用户可以修改的所有对象;
  2. 如果我选择一个对象,检查登录用户是否可以删除它;

附两张数据库图

db1 db2

我试过了

  1. 对象模型中的范围 withWhereHas 但我对如何检查权限感到困惑
Object::withWhereHas('roles', function($query) {
            $query->whereHas('users', function($query2){
                $query2->where('id',auth()->id());
            });

        });
  1. 在对象模型中使用 using('acls'),但我坚持如何检查权限,而且我还获取未链接到登录用户所属角色的对象
Object::with(['roles' => function($query){`your text`
            $query->whereHas('users', function($query2){
                $query2->where('id',auth()->id());
            });
        }]);

我向您寻求最佳程序的建议

eloquent permissions laravel-8 acl eloquent-relationship
1个回答
0
投票

为了满足您管理修改和删除对象的用户权限的要求,让我们首先分解问题:

  1. 检索登录用户可以修改的所有对象。
  2. 检查登录用户是否可以删除特定对象。

假设

  • 角色和权限:对象与角色关联,角色与用户关联。
  • 权限:每个角色都有特定的权限(例如,
    can_modify
    can_delete
    )。

使用雄辩的范围和关系

Eloquent 的关系和查询范围可以简化数据查询。以下是分步指南:


第 1 步:数据库架构概述

假设您有以下表格:

  1. users
    :存储用户信息。
  2. roles
    :存储角色(例如管理员、编辑)。
  3. objects
    :代表被管理的对象。
  4. role_user
    :链接
    users
    roles
    的数据透视表。
  5. object_role
    :链接
    objects
    roles
    的数据透视表。

其他字段

  • object_role
    表可以包含
    permission
    字段(
    can_modify
    can_delete
    )来存储特定权限。

第 2 步:定义模型中的关系

用户模型

class User extends Authenticatable
{
    public function roles()
    {
        return $this->belongsToMany(Role::class, 'role_user');
    }
}

榜样

class Role extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class, 'role_user');
    }

    public function objects()
    {
        return $this->belongsToMany(Object::class, 'object_role')->withPivot('permission');
    }
}

对象模型

class Object extends Model
{
    public function roles()
    {
        return $this->belongsToMany(Role::class, 'object_role')->withPivot('permission');
    }
}

第 3 步:定义检索可修改对象的范围

Object
模型中添加查询范围来过滤用户可以修改的对象:

class Object extends Model
{
    public function scopeModifiableBy($query, $userId)
    {
        return $query->whereHas('roles', function ($query) use ($userId) {
            $query->whereHas('users', function ($query) use ($userId) {
                $query->where('id', $userId);
            })->wherePivot('permission', 'can_modify');
        });
    }
}

用途:

$modifiableObjects = Object::modifiableBy(auth()->id())->get();

第 4 步:检查特定对象的删除权限

创建一个方法来检查登录用户是否可以删除特定对象:

class Object extends Model
{
    public function canBeDeletedBy($userId)
    {
        return $this->roles()->whereHas('users', function ($query) use ($userId) {
            $query->where('id', $userId);
        })->wherePivot('permission', 'can_delete')->exists();
    }
}

用途:

$object = Object::find($objectId);

if ($object->canBeDeletedBy(auth()->id())) {
    // User can delete this object
} else {
    // User cannot delete this object
}

第五步:利用Eloquent关系提高查询效率

您提到了获取未链接到角色的对象的问题。为了确保只检索相关对象:

  • 使用
    has()
    过滤链接到具有权限的角色的对象。

示例:

$objects = Object::whereHas('roles', function ($query) {
    $query->whereHas('users', function ($query) {
        $query->where('id', auth()->id());
    });
})->get();

第六步:调试和优化

  • 确保数据透视表(
    role_user
    object_role
    )已正确配置所有必需的关系和字段。
  • 使用 Laravel 的 调试工具
    dd()
    toSql()
    )来检查查询并排除故障。
  • 向查询中经常使用的数据透视表字段添加索引(例如,
    role_id
    object_id
    user_id
    )。

政策的替代方法

对于更复杂的权限处理,请考虑使用 Laravel 策略。为

Object
模型定义策略并管理权限逻辑:

php artisan make:policy ObjectPolicy

ObjectPolicy

public function modify(User $user, Object $object)
{
    return $object->roles()->whereHas('users', function ($query) use ($user) {
        $query->where('id', $user->id);
    })->wherePivot('permission', 'can_modify')->exists();
}

public function delete(User $user, Object $object)
{
    return $object->roles()->whereHas('users', function ($query) use ($user) {
        $query->where('id', $user->id);
    })->wherePivot('permission', 'can_delete')->exists();
}

在控制器中:

if ($user->can('modify', $object)) {
    // Logic for modifying the object
}

if ($user->can('delete', $object)) {
    // Logic for deleting the object
}
© www.soinside.com 2019 - 2024. All rights reserved.