【问题标题】:Where to put rights management logic in MVC software architectureMVC软件架构中权限管理逻辑放在哪里
【发布时间】:2017-08-08 18:17:03
【问题描述】:

假设我的模型在用户使用时受权,但在业务逻辑使用时不受权。

例如: 当一个人创建一个项目 A 时,它会自动创建一个项目 B。

如果用户想要创建 A 或 B,他必须有权创建 A 或 B。 但是从 A 创建 B 时的业务逻辑不需要任何权限。

如果我将正确的系统放在业务逻辑中,我会得到对会话有很强依赖性的类,如果登录用户没有权限,A 就无法创建 B。

如果我将权限管理放在控制器中,我觉得我的业务逻辑不安全,因为任何程序员都可能忘记在创建项目之前测试权限并且不会被停止,而且如果 2 个控制器能够进行代码复制,则会出现代码重复出于任何原因更新项目。

你会把权限管理放在哪里?

我可以创建控制器使用的每个对象的继承,并实现权限限制,而业务逻辑将访问对象本身。控制器创建 UserA、UserB,而对象 A 直接创建 B 对象。 但听起来我必须复制(继承)必须在控制器中使用的每一个业务逻辑对象,因此其中有 80% 是固定的。

【问题讨论】:

  • 你应该为你的类举一个具体的例子。很难理解 A 类和 B 类是什么。 A 是用户模型吗?
  • 你有中间件吗?您还可以使用服务来共享代码

标签: php model-view-controller rights


【解决方案1】:

我会建议你使用 laravel 来做同样的事情。 Laravel 提供了你需要在路由文件中指定的中间件。因此,每次调用任何控制器时,都必须调用第一个中间件,然后检查所有条件,然后将其转发给控制器。

在中间件中,您可以创建一个类文件来检查角色和权限或必要的权限。

您可以参考https://heera.it/laravel-5-1-x-acl-middleware

或者喜欢https://github.com/Zizaco/entrust#user-relation-to-roles

【讨论】:

    【解决方案2】:

    这是一个例子:

        <!-- language: php -->
    //abstact Model
    abstract class Models {
        public function save() {
            if($this->id === null) {
                $this->insert();
            } else {
                $this->update();
            }
        }    
    
        abstract protected function insert() {
            //insertion in DB
        }    
    
        abstract protected function update() {
            //update in DB
        }
    }    
    
    
    //A Model
    class A extends Model {
        protected function insert() {
            //check if logged in user can insert A objects otherwise throw an exception
            //insert in DB    
    
            $b = new B;
            //set $b datas
            $b->save();
        }    
    
        protected function update() {
            //check if logged in user can update A objects and has rights on instanciated A otherwise throw an exception
            //update in DB
        }
    }    
    
    //B Model
    class B extends Model {
        protected function insert() {
            //check if logged in user can insert B objects otherwise throw an exception
            //insert in DB
        }    
    
        protected function update() {
            //check if logged in user can update B objects and has rights on instanciated B otherwise throw an exception
            //update in DB
        }
    }    
    
    //A Controller
    class AController() {
    
        public function createA() {
            $a = new A;
            //set $a datas
            $a->save()
        }    
    
        public function updateA($id) {
            $a = new A($id);
            //set new $a datas
            $a->save()
        }
    }    
    
    //B Controller
    class BController() {
    
        public function createB() {
            $b = new B;
            //set $b datas
            $b->save()
        }    
    
        public function updateB($id) {
            $b = new B($id);
            //set new $b datas
            $b->save()
        }
    }
    

    如果我将验证保留在模型中,如果用户不能创建对象 A,则对象 A 不能创建对象 B,但应该因为在此示例中创建 B 的不是用户,而是通过 A 代码的业务逻辑。

    如果我从模型中取出验证并将其放入控制器中,我会遇到一个程序员,他们可能会忘记验证,并且当不同的控制器应该更新一个项目时可能会有很多重复。

    到目前为止,我想到了:

    • 1 在控制器中进行权限检查,但听起来并不安全
    • 2 注入用户,但我必须创建一个供业务逻辑使用的“所有权限”用户
    • 3 在 save() 方法上添加一个 $norights 选项,该选项默认为 false,但由业务逻辑设置为 true 以越过权限检查

    出于不同的原因,这些想法都不能完全满足我:

    • 如果忘记检查,则 1 个不安全模型
    • 2 超级用户听起来不太好
    • 3 听起来很脏

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-10
      • 1970-01-01
      • 2013-10-19
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2014-03-16
      相关资源
      最近更新 更多