在 API 级别按方法进行 ACL 检查
我正在开发一种 MVC 框架,并且正在实现一个简单的 ACL 权限检查系统。
我想知道是否有人可以阐明,或者指导我一些此类实现的好例子(或者批评到需要废弃它的程度,无论哪一个是必要的),
因为我正在使用 REST API 构建框架请注意,我创建了两个基本控制器:WebController
和 ApiController
。
对 /index.php
发出的请求路由至 WebController_*
,对 /api/index.php
发出的请求路由至 ApiController_*< /code>
扩展的 WebController
负责从模板构建输出,并使用从对必要的 ApiController
的合并调用返回的数据。
扩展的 ApiController
负责查询 Model
中的数据。如果直接调用 /api/index.php
,它将返回 JSON
。
但是我离题了;为了促进 ACL,我认为在 ApiController 层实现它是有意义的,如果存在拒绝,则会以 JSON 返回/code> 或备份到 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
}
}
}
好主意?坏主意?有什么想法吗?也许我有点不知所措,我仍在学习,这更多的是为了教育而不是为了利润,但是完成一些将来有用的东西会很好。
I'm working on a sort of MVC framework, and I'm implementing a simple ACL permissions check system.
I'm wondering if anyone can shed some light on, or direct me towards some good examples of this sort of implementation (or criticize to the point of warranting scrapping it, whichever is necessary)
Since I'm building the framework with REST API in mind, I've created two base controllers, WebController
and ApiController
.
Requests made to /index.php
route to WebController_*
and requests made to /api/index.php
route to ApiController_*
An extended WebController
is responsible for building output from a template with data returned from the consolidated calls to the necessary ApiController
s.
An extended ApiController
is responsible for querying the Model
for data. If a call is made directly to /api/index.php
it returns JSON
.
But I digress; In order to facilitate ACL, I figured implementing it at the ApiController
layer made sense, and if there is a denial it is returned in JSON
or back up to a WebController
and handled accordingly, depending on the request type.
I'm thinking to simplify things, I could make use of __call()
and private methods. __call()
would verify the existence of the requested method, and prior to calling it, check the user permissions on the method it against the 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
}
}
}
Good idea? Bad idea? Thoughts? Maybe I'm in over my head here, I'm still learning and this is more for education than profit, however finishing something that has future use would be nice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
ApiController
层中检查凭据是一个非常好的主意,但尝试通过避免使用__call()
方法来消除魔力。是的,这不是您的问题,但如果您想要更好的性能,这可能会很有用。那么,您可以使用过滤器,例如安全过滤器,它处理请求并检查用户权限。例如,过滤器可以将请求重定向到 401 错误响应。
这个想法来自 Symfony 框架。
问候,
威廉.
This is a pretty good idea to check credentials in the
ApiController
layer but try to kill the magic by avoiding the__call()
method. Yes, this isn't your question but could be useful if you want better performances.Well, you may use filters like a security filter which handles the request and check the user permissions. The filter could redirect the request to the 401 error response for example.
This idea comes from the Symfony Framework.
Regards,
William.
我决定采用与我最初提出的方法类似的方法,创建一个
Gateway
对象来充当Model
的代理。本质上,Gateway
对象保存对Acl
、Request
和Model
对象的引用,并针对在将任何方法调用转发到Model
之前,Acl
对象。为简洁起见,进行了简化:这种方法存在任何问题吗?据我所知,这应该非常有效地达到目的,因为我可以在不同的
Acl 和
Model
对象基于Controller
的需要(尽管可能只需要一个Acl
)此外,我的API 调用的路由变得简单,因为使用 REST/RPC 混合架构,API 调用可以传递到
网关
,而不需要太多修改。I've decided to go with an approach similar to my initially proposed method, creating a
Gateway
object to act as a proxy to theModel
. Essentially theGateway
object holds a reference to theAcl
,Request
, andModel
objects, and performs checks against theAcl
object before forwarding any method calls to theModel
. Simplified for brevity:Are there any issues that can be seen with this approach? So far as I can tell, this should serve the purpose quite effectively, as I can sub in different
Acl
andModel
objects based on the needs of theController
(Though likely there will only be the need for a singleAcl
)Furthermore, my routing of API calls becomes simplified, as using a REST/RPC hybrid architecture, API calls can be passed to the
Gateway
without much need for modification.