检查用户是否有权访问实体的最佳方法是什么

时间:2015-03-02 23:14:10

标签: php laravel laravel-4 eloquent

我在数据库中简化了以下关系。

1 User -> n Projects
1 Project -> n Tasks
etc.

所以现在我经常在代码中发现自己以下

// Get the current logged in User
$user = Session::getUser();
$project = $this->projects->findById($project_id);
if ( ! $project->hasOwner($user))
   // user does not own the project

随着项目的关系,情况会变得更糟。例如,我必须检查用户是否拥有项目,然后检查任务是否属于项目。

我当时想在这里使用Eager Loading,所以我可以过滤给定的结果。但随后数据库必须加载更多数据,然后经常需要。对吗?

// Get the current logged in User
$user = Session::getUser();
$project = $user->projects()->find($project_id);
if ( ! $project)
   // user does not own the project

但即使我这样做,也感觉重复和黑客。我想知道是否有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

虽然用户可以访问他们的项目,但您需要为将来与其他用户共享项目及其访问类型做好准备。

因此,强烈建议使用project_permission表。

结构应如下:

id | project_id | grantee_user_id | access_user_id |类型| created_at | updated_at | deleted_at

您将拥有3种类型的权限:

  1. 所有者 - 完全许可
  2. 修改权限
  3. 只读访问
  4. 您的权限模型:

    class ProjectPermission extends Eloquent {
         protected $table = "project_permission";
    
         /*
         *  Types
         */
    
         const OWNER = 1;
         const EDIT = 2;
         const READ = 3;
    
         /*
         *  Scopes
         */
    
        public function scopeOwner($query)
        {
            return $query->whereType(self::OWNER);
        }
    
        public function scopeEdit($query)
        {
            return $query->whereType(self::EDIT);
        }
    
        public function scopeRead($query)
        {
            return $query->whereType(self::READ);
        }
    
        public function project()
        {
            return $this->belongTo('Project','project_id');
        }
    
    }
    

    和项目模型:

    class Project extends Eloquent {
        ...
        //Always eager load project permission
        public $with = ['permission'];
    
        public function permission()
        {
            return $this->hasMany('ProjectPermission','project_id');
        }
    
        public function scopeUserIsOwner($query,$user_id)
        {
            return $query->has('permission'=>function($q){
                return $q->owner()->where('access_user_id','=',$user_id);
            });
        }
    
        public function scopeCurrentUserIsOwner($query,$user_id)
        {
            $user = Session::getUser();
            $user_id = $user ? $user->id : 0;
    
            return $query->has('permission'=>function($q){
                return $q->owner()->where('access_user_id','=',$user_id);
            });
        }
    
        /*
        *  @param int $user_id
        *  @return boolean
        */
        public function hasAccessOwner($user_id)
        {
            return (bool)$this->permission()->whereType(\ProjectPermission::OWNER)->->whereAccessUserId($user_id)->count();
        }
    }
    

    理想情况下,您应该只加载用户有权访问的项目。如果需要检查访问权限,hasAccess..函数将证明是方便的。