1
186
在我看来,最好的方法是使用 decorator pattern ,基本上,这意味着你拿着你的物体 里面 另一个物体,就像一个保护壳。这不需要您扩展原始类。举个例子:
您可能注意到,此解决方案有几个优点:
,这个方法也有一个主要问题-您不能以本机方式检查安全对象是否实现和接口(这也适用于查找现有方法)或者是某个继承链的一部分。 第二部分/答案(对象的RBAC)
在这种情况下,您应该认识到的主要区别是
基本上你有两个选择:
两个视频可能会帮助您提出自己的实现:
您似乎对MVC中的模型有着非常普遍(而且完全错误)的理解。
模型不是类
. 如果你有一个叫
域业务逻辑这组类中的实例处理值的计算、检查不同的条件、实现销售规则以及完成所有其他您称之为“业务逻辑”的工作。他们不知道数据是如何存储的,存储在哪里,甚至不知道存储是否首先存在。
数据存取和存储Data Mapper 模式(不要与同名的ORMs混淆。。没有关系)。这就是SQL语句的位置(或者DomDocument,因为它存储在XML中)。 除了两个主要部分之外,还有一组实例/类,应该提到: 服务这就是您和第三方组件发挥作用的地方。例如,您可以将“身份验证”视为服务,它可以由您自己提供,也可以由一些外部代码提供。“邮件发送者”也是一种服务,它可以将一些域对象与PHPMailer或SwiftMailer或您自己的邮件发送者组件组合在一起。 另一个来源 services 是对域和数据访问层的抽象。创建它们是为了简化控制器使用的代码。例如:创建新用户帐户可能需要与多个 域对象 和 映射器 . 但是,通过使用服务,它只需要控制器中的一条或两条线。 在创建服务时,您必须记住的是,整个层应该是 . 服务中没有业务逻辑。它们只用于处理域对象、组件和映射器。 它们的一个共同点是,服务不会以任何直接的方式影响视图层,并且在某种程度上是自治的,因此它们可以(并且经常)在MVC结构本身之外使用。此外,由于服务和应用程序其余部分之间的耦合性极低,这种自我维持的结构使得迁移到不同的框架/体系结构变得更加容易。 |
2
16
首先:这些通常是不同的事物/层次。当您批评示例性控制器代码时,它将两者结合在一起—最明显的是过于紧密。 我会先退一步,找出你面临的最初问题,然后再讨论一下。
另一方面,您希望能够在应用程序中放置ACL。这些ACL的工作领域应该是——如果我理解你的问题的话——控制对应用程序某些命令的访问。 因此,这种访问控制需要将这两者结合在一起的其他东西。根据执行命令的上下文,ACL启动,需要决定特定的主体(例如用户)是否可以执行特定的命令。
ACL组件在这里是中心的:它至少需要知道一些关于命令的信息(准确地说是识别命令),并且需要能够识别用户。用户通常很容易通过一个唯一的ID来识别。但是在Web应用程序中,通常有一些用户根本不被识别,通常称为guest、anonymous、everybody等。。对于本例,我们假设ACL可以使用一个用户对象并封装这些细节。用户对象绑定到应用程序请求对象,ACL可以使用它。 如何识别命令?您对MVC模式的解释表明,命令是类名和方法名的复合。如果我们仔细看,甚至还有一个命令的参数。因此,问什么确切地标识一个命令是有效的?类名,方法名,参数的个数或名称,甚至参数中的数据,还是所有这些的混合?
因此,这三个部分(ACL、Command和User)是如何相互归属的上下文现在变得更加清楚了。 我们可以说,使用一个虚构的ACL组件,我们已经可以执行以下操作:
看看这里发生了什么:通过使命令和用户都可识别,ACL可以完成它的工作。ACL的作业与用户对象和具体命令的工作无关。 只有一个部分不见了,这不能在空气中生存。但事实并非如此。所以你需要找到访问控制需要启动的地方。让我们看看标准Web应用程序中会发生什么:
要定位该位置,我们知道它必须在具体命令执行之前,因此我们可以减少该列表,只需要查看以下(潜在)位置:
在应用程序的某个时刻,您知道某个特定的用户请求执行一个具体的命令。您已经在这里执行了某种ACL'ing:如果用户请求的命令不存在,则不允许执行该命令。因此,应用程序中发生的任何情况都可能是添加“真正的”ACL检查的好地方:
命令已经被定位,我们可以创建它的标识,这样ACL就可以处理它了。如果用户不允许该命令,则不会执行该命令(操作)。也许是一个
将具体HTTPRequest的映射映射到命令的位置通常称为
路由
路由
已经有了定位命令的作业,为什么不扩展它来检查每个ACL是否允许该命令呢?例如,通过延长
用户从一开始就可用,先用命令
所以不要把你的ACL检查放进去 命令的具体实现,你把它放在它前面。你不需要任何繁重的模式,魔法或其他什么,ACL做它的工作,用户做它的工作,尤其是命令做它的工作:只是命令,没有别的。命令没有兴趣知道角色是否应用于它,它是否在某个地方受到保护。 单一责任原则(SRP) :更改命令的原因只有一个-因为命令已更改。不是因为您现在在应用程序中引入了ACL'ing。不是因为你切换了用户对象。不是因为您从HTTP/HTML接口迁移到SOAP或命令行接口。 本例中的ACL控制对命令的访问,而不是命令本身。 |
3
13
一种可能是将所有控制器封装在另一个扩展控制器的类中,并让它在检查授权后将所有函数调用委托给封装的实例。 您还可以在调度程序(如果您的应用程序确实有一个)的上游执行更多操作,并基于url而不是控制方法查找权限。 编辑 :是否需要访问数据库、LDAP服务器等与问题正交。我的观点是,您可以实现基于url的授权,而不是基于控制器方法。这些功能更强大,因为您通常不会更改URL(类似于公共接口的URL区域),但您也可以更改控制器的实现。 通常,您有一个或多个配置文件,可以在其中将特定的URL模式映射到特定的身份验证方法和授权指令。调度器在将请求分派给控制器之前,确定用户是否被授权,如果用户没有被授权,则中止分派。 |
Jacco · 未能格式化我的日期以在php中正确工作 1 年前 |
jay ram · 如何在URL核心php中从API获取JSON? 1 年前 |
Ishwarya A · php电子表格在浏览器中显示多张excel 1 年前 |