PHP面向对象编程 - 如何处理授权?

6
我是一名有用的助手,可以为您提供文本翻译。以下是需要翻译的内容:

我正在构建一个管理系统来实现我的想法。我对PHP非常熟悉(至少足够做我需要做的一切),但我在使用OOP方面并不那么有经验。我尽可能多地使用它,但很多最佳实践我不熟悉,所以当我做事情时,我担心我按错误的顺序进行。

对于这个项目,我有一个类来管理用户管理的内容,我需要检查用户是否有管理权限。我知道如何检查权限,我的问题是:我应该在哪里进行检查?

我应该在类外部进行检查,像这样:

if user permissions are valid
initialize class
else return error

或者我应该做什么?
initialize class
class checks permissions 
class returns error if permissions are invalid

我不确定哪种方法是正确的。一方面,根据我对面向对象编程方法论的了解,在类内部进行检查似乎是最好的选择,但另一方面,当权限未知时,让它初始化类可能会很糟糕。
应该如何处理?如果有任何涉及此类问题的文章,链接将非常感激(我无法通过搜索找到任何东西,但我不确定我是否正在搜索正确的内容,因为我对面向对象编程知之甚少)。
5个回答

4
这取决于您的权限模型,没有“唯一正确的方法”可以做到这一点。这是一种方法论问题。重要的是,无论您选择什么,都要始终如一地使用它。
在我的最新项目中,我遇到了几种不同的模型。其中一个最直接的是基于页面的权限,如果您进行基于页面的流程并使用对象支持,则很好:您在页面顶部定义谁应该访问它,并在必要时可以重定向。这是最简单的一种,但在特定应用程序上非常有用。
相反,如果您使用对象执行主要流程,则应保护您的对象方法(而不是类实例化)。如果您有一个“save()”方法,只能由特定用户调用,请在进入该方法时首先进行权限检查。
我目前正在使用MVC模式,我有一个控制器,将操作分派给其子级。它唯一的公共方法是execAction($params),它将在自身上调用actionAction($params),但首先会检查权限。
记住一件重要的事情:除非您试图强制他购买您的“PRO版本”,否则不要在UI上呈现用户无法执行的操作;-)

在某些系统中,您可以通过动态地(从浏览器开发工具中)向页面添加HTML来使某些操作对您可用。因此,请检查这些操作。 - Imre L

1

我已经编写了一个相当稳定和健壮的CMS系统。以下是我的实现方式,希望能为您制作自己的解决方案提供一些信息。

  • 我有一个索引文件,它加载一个Admin类。我的CMS功能是模块化的(因此包含在自己的文件和类中)。
  • 基于$_GET参数加载模块。
  • 因为检查$_GET参数并加载相应函数的函数在我的Admin类中($admin->pick_method()),而且我还在我的Admin类中拥有一个User对象,所以我可以首先检查请求的模块是否在当前登录用户的权限数组中。
  • 如果权限检查返回true,则加载模块。如果返回false,则显示友好的“未经授权访问”页面。

希望这能帮到您。


0

在类内部进行验证会在类和权限授权之间产生依赖关系,这并不好,因为您正在将两个潜在的不同项目联系在一起。 您可以通过 IoC(控制反转)(例如 依赖注入),或者像我一样使用Emesary 权限通知 来解决这个问题。

在类外部进行验证可能更糟,因为有真正的危险,授权检查将是错误的或完全被忽略掉。 它还会创建对象之间错误类型的连接,因为对象无法控制自己。

如果您将其移至对象创建时之外,则最好要求对象提供 接口,例如 IAuthorisable,该接口可以由单独的对象进行验证。

例如:

interface IAuthorisable
{
    public function getRequirements();
}

class Authorisation
{
     public static createObject($newObj)
     {
          if ( canDo( $newObj->getRequirements()) )
              return $newObj;
          return null;
     }
}

class Something implements IAuthorisable
{
     public function getRequirements()
     { 
          return SomeSortOfIdentifierOrSomething;
     }
}

$mySomething = Authorisation::createObject(new Something($p1, $p2), "

如果$mySomething为空,则不允许。显然,这需要进行适当的扩展和设计,这留给读者作为练习。

0

我认为最好的方法是创建一个权限类。然后在创建对象之前或对象内部进行检查。

create permission class
if access then create class and set permission object
else error
// do action
if have permissions show something
else do not show something

看看 Zend ACL 组件 是如何完成的。


0

面向对象基础
如果在类中包含它是有意义的,你可以这样做。
一个Book类是否有认证功能?不,像download()和convertToPDF()这样的函数更有意义。

我的方法
我总是试图找到最小阻力的路径。

如果有10个脚本/页面与1个类交互,并且1或2个脚本需要对某些操作进行身份验证,我会将身份验证构建到这1或2个脚本中(或将它们放入带有.htpasswd的子文件夹中)。

但是当您使用MVC结构时,一切都是类,因此问题变成了决定哪个类。
我倾向于将身份验证规则放在控制器类中,并将身份验证逻辑放在用户类中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接