【问题标题】:How is it possible to manage users' permission on specific data in Backpack for Laravel?如何在 Backpack for Laravel 中管理用户对特定数据的权限?
【发布时间】:2021-01-06 18:04:33
【问题描述】:

我将 laravel-backpack admin 用于我的应用程序的管理部分,并使用 PermissionManager 来管理用户角色和权限。现在我想分配对特定数据的特定访问权限。

例如,假设我们有一个文章管理系统,并且我们有一个editor 角色及其用户名为user24 的用户的相关权限,因此所需的方法是user24 必须访问到他们的仪表板或 crud 列表中的特定文章,如 article 1。

Articles 表结构:

注意:“user_id”字段指的是文章的所有者。

|---------------------|------------------|------------------|   
|      id             |     title        |     user_id      |
|---------------------|------------------|------------------|
|          1          |     article1     |        2         |
|---------------------|------------------|------------------|

【问题讨论】:

    标签: laravel laravel-backpack


    【解决方案1】:

    方法一:

    实现此目的的一种方法是创建第二个名为CrudArticle(或其他)的类,使其扩展原始 Article 类,然后向此模型添加一个全局范围,将所有查询限制为使用该类的表仅包括属于当前用户的记录。将此类与您的 CRUD 面板和应用程序中其他地方的普通 Articles 类一起使用。

    class CrudArticle extends Article {
    
        public static function boot()
        {
            parent::boot();
            
            // only include models that belong to this user
            $user_id = 0;
            Auth::check();
            if ($user = Auth::user()) {
                $user_id = $user->id;
            }
            static::addGlobalScope('userFilter', static function (Builder $builder) use ($user_id){
                $builder->where('user_id', $user_id);
            });
        }
    }
    

    注意:这将防止非拥有记录出现在列表页面上,并防止通过直接 url 加载编辑页面。但是,我不能 100% 确定仅上述内容就可以防止插入(将请求直接发布到更新端点),也就是说,您可能仍然需要更改下面第二种可能的解决方案中推荐的“UpdateRequest”


    方法二:

    实现此目的的另一种方法是修改 CRUD 使用的查询,例如,在您的 CRUD 控制器中:

    /**
     * Set up the "list" or "read" operation for the resource
     */
    public function setupListOperation(): void
    {
        // ... normal setup code ...
    
        Auth::check();
        $user = Auth::user();
        if (!$user) {
            throw new \Exception('Unauthorized');
        }
        $this->crud->query = $this->crud->query->where('user_id', $user->id);
    }
    

    为了防止通过直接 url 查看更新页面,您可以在 setupUpdateOperation 中添加如下内容:

    /**
     * Set up the "update" operation for the resource
     */
    public function setupUpdateOperation(): void
    {
        // ... normal setup code ...
        
        $authorized = false;
        // only allow viewing the update page if the user is logged in and owns the Article
        Auth::check();
        if ($user = Auth::user()) {
            $id = $this->get('id');
            $product = Article::find($id);
            if ($product) {
                $authorized = $product->user_id === $user->id;
            }
        }
        if (!$authorized) {
            $this->crud->denyAccess(['update']);
        }
    }
    

    为防止未经授权的编辑直接发布到更新端点,您还需要在 UpdateRequest 中添加如下内容:

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        $authorized = false;
        // only allow updates if the user is logged in and owns the Article
        Auth::check();
        if ($user = Auth::user()) {
            $id = $this->get('id');
            $product = Article::find($id);
            if ($product) {
                $authorized = $product->user_id === $user->id;
            }
        }
        return $authorized;
    }
    

    或者,您也可以add a global scope to the model in question as explained here,但我倾向于避免这样做,因为它会改变整个应用程序的行为

    【讨论】:

    • 感谢您的回答,但提到的user_id 字段指的是文章的所有者,因此我想将访问权限分配给不是文章所有者的其他用户。
    • @MeysamZarei 嗯,我不确定我是否理解那里的用法,但是,同样的原则适用,您只需将条件更改为您需要的任何条件。
    • 你是对的。我一直在寻找一个图书馆或其他东西来很好地完成这项工作,但我没有找到任何东西。所以正如你所说,这似乎是适当的原则,在我看来,我应该用它来处理提到的问题。
    猜你喜欢
    • 2021-11-13
    • 2021-01-31
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2022-01-15
    • 2020-04-25
    • 1970-01-01
    • 2020-02-20
    相关资源
    最近更新 更多