【问题标题】:ACL checks at API level, on a per-method basisACL 在 API 级别检查,基于每个方法
【发布时间】:2011-02-28 22:42:08
【问题描述】:

我正在开发一种 MVC 框架,并且我正在实现一个简单的 ACL 权限检查系统。

我想知道是否有人可以解释一下,或者指导我寻找一些这种实现的好例子(或者批评到保证废弃它的地步,无论是必要的)

由于我在构建框架时考虑到了 REST API,因此我创建了两个基本控制器,WebControllerApiController

/index.php 的请求路由到WebController_*,对/api/index.php 的请求路由到ApiController_*

扩展的WebController 负责构建模板的输出,其中包含从对必要ApiControllers 的合并调用返回的数据。

扩展的ApiController 负责查询Model 的数据。如果直接调用/api/index.php,则返回JSON

但我跑题了;为了方便 ACL,我认为在 ApiController 层实现它是有意义的,如果有拒绝,它会在 JSON 中返回或备份到WebController 并根据请求类型进行相应处理。

我正在考虑简化事情,我可以使用__call()private 方法。 __call() 将验证请求的方法是否存在,并在调用它之前,根据 ACL 检查该方法的用户权限。

class ApiController{

    public function __call($method, $arguments){
        if(method_exists($this, $method)){
            //haven't written ACL classes yet, but something like this
            if(ACL::check(...)){ 
                return call_user_func_array(array($this, $method), $arguments);
            }else{
                return false;
            }
        }else{
            //throw catchable exception or something
        }
    }

}

好主意?馊主意?有什么想法吗? 也许我在我的头脑中,我还在学习,这更多的是为了教育而不是为了利润,但是完成一些有未来用途的东西会很好。

【问题讨论】:

    标签: php model-view-controller acl


    【解决方案1】:

    这是检查ApiController 层中的凭据的好主意,但要避免使用__call() 方法来消除魔法。是的,这不是您的问题,但如果您想要更好的性能,这可能会很有用。

    好吧,您可以使用过滤器,例如处理请求并检查用户权限的安全过滤器。例如,过滤器可以将请求重定向到 401 错误响应。 这个想法来自Symfony Framework

    问候, 威廉。

    【讨论】:

    • 谢谢威廉;我试图避免硬调用 ACL 检查方法,无论是在 ApiController 方法调用之前,还是在 in ApiController 方法调用之前。我一直在阅读有关观察者模式的内容,也许这就是我应该采取的方向。 __call() 似乎是个好主意,但如果有其他方法可以强制这种行为,我会全力以赴。
    • 是的,观察者模式是一个不错的方法。这是一个很好的 PHP 实现:Event dispatcher
    【解决方案2】:

    我决定采用类似于我最初提出的方法的方法,创建一个Gateway 对象作为Model 的代理。本质上,Gateway 对象包含对AclRequestModel 对象的引用,并在将任何方法调用转发到Model 之前对Acl 对象执行检查。为简洁起见简化:

    public function __call($method, $arguments){
        // check request data against acl
        if($this->_acl->check($this->_request, $method, $arguments)){
            // on success, send request in and forward method to model
            $this->_model->setRequest($this->_request);
            return call_user_func_array(array($this->_model, $method), $arguments);
        }
        // acl check failed, no access
        return false;
    }
    

    这种方法有什么问题吗?据我所知,这应该可以非常有效地达到目的,因为我可以使用不同的AclModel基于Controller 需求的对象(虽然可能只需要一个Acl

    此外,我的 API 调用路由变得简化了,因为使用 REST/RPC 混合架构,API 调用可以传递到 Gateway 而无需太多修改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 2021-08-27
      • 1970-01-01
      • 2019-02-04
      相关资源
      最近更新 更多