2011-04-27 49 views
1

在此处进行另一个讨论,了解如何进行身份验证或更有可能进行身份验证。谁应该认证用户。验证用户的身份/验证PHP OO

考虑下面的代码示例:

<?php 
class User { 
    public function isValid($username, $password) { 
     //Logic to check if username/password match 
     $this->setId($id); 
    } 
} 

<?php 
class Auth { 
    public function isValid($username, $password) { 
     //Logic to check if username/password match 
     $user = new User; 
     $user->setId($id); 
     return $user; 
    } 
    } 

我personnaly给下面的例子,为什么在这种情况下,#1不好: 如果允许用户验证自理。他们会走进电影院。他们可以走进任何电影。只要对自己说,他们是有效的。

其中第二个示例有一个外部对象检查用户的有效性。因此更“啪”

请注意,我在OOP编程中没有任何教育,这可能是我在'08或'09开始编码时读回的东西:)我希望这里有些人知道我的意思,并且可以然后解释这里的好/坏做法。

由于正在进行

+1

仅仅是用来迷惑你:第三个方案。 'class User {public static function authenticate($ username,$ password){/ * test */return $ user; }}':)它是我更喜欢的方式。但是,我不认为有这样的方式。这取决于你的应用程序( - 设计)。 – KingCrunch 2011-04-27 10:39:09

+0

我更喜欢第二种解决方案。看看Zend Framework的'Zend_Auth'解决了这个问题,并且很好地构建。 'Zend_Acl'也可能很有趣。 – 2011-04-27 10:56:36

+0

我们目前有一个似乎可以工作的RBAC系统。只是解决我们想要验证用户身份的问题。无论是在用户对象本身还是在一个独立的类中 – Tjirp 2011-04-27 10:58:55

回答

2

逻辑应是对用户有两个原因:

  1. 其耦合以一定的后端验证到用户
  2. 所述方法外部的参数,而不是对象成员操作逻辑。

现在,你可以

class User … 
    public function authenticate(Authenticable $adapter) 
    { 
     $this->isAuthenticated = $adapter->authenticate(
      array(
       'username' => $this->username, 
       'password' => $this->password, 
      ) 
     ); 
    } 
} 

这个蕴藏着一个问题:为什么(以及如何)分离认证逻辑(1)和工作的对象成员(2)密码应完全存储在用户上。你当然不想在那里有明文。在我看来,密码的哈希不是用户的责任。事实上,如果你不添加salt给用户,那么你不能在用户中进行哈希,这是我不会想到的典型用户属性。您可以散列密码以在$ adapter中使用salt来重新散布它,但那只是治愈症状。在OOP中,对象方法应该对一个对象的成员进行操作。但是,如果密码首先不应该是用户的成员,则使用它的方法不应该在用户(cohesion)上。不用说,如果您使用的是ActiveRecord,您可能会拥有类似上述的内容,或者将身份验证方法作为用户的静态方法,然后返回实例。就个人而言,我不喜欢AR和静态方法,所以我会用一个单独的Authentication Service类来为我返回Users。

+0

您的第二点可以通过创建一个新的用户对象来取消。通过表单设置给定的用户名和密码,并运行验证属性的验证功能。 (尽管我不想那样!!))我认为到目前为止,第一个是我可以用来说服我的同事的最有说服力的。像akamike也解释。我们为用户提供的数据库行包含当前的用户名,散列和盐。盐每行独特的地方。将它从用户行中删除并将其添加到另一个表中有什么好处?用户对象本身并不知道盐是否存在 – Tjirp 2011-04-27 11:36:06

+0

@Tjirp我实际上在我的示例代码中同时强调了这两点。它不是无效的。你所描述的是上面的例子应该显示的:拥有一个用u/p作为对象成员的User对象。代码段下面的段落解释了为什么这是一个坏主意。密码不属于用户(盐都没有)。你想要凝聚力。 – Gordon 2011-04-27 12:00:11

1

User对象将是用户配置文件的模型,拿着详细信息,如用户名,密码,电子邮件等,但理论上可以有网站上的资料,而不需要连接,要一个登录名(可能只有一个主管理员可以编辑配置文件)。

您的Auth类将处理登录检查,因为我想这也将处理设置和删除用户会话,这是与实际用户配置文件分开的。

  • User =模型用户数据
  • Auth =逻辑认证

认为它这样,如果你决定怎么改您的个人资料认证作品(或许删除自己的登录过程,用Twitter OAuth替换它),将认证逻辑从用户配置文件中分离出来可以使这更容易。

+0

作为一个方面说明,你的示例方法'isValid()'表明它应该返回一个布尔值而不是有效的用户配置文件。你应该使用'isValid()'检查一个有效的会话,然后使用类似'getLoggedInUser()'的方法拉出已登录的配置文件。 – akamike 2011-04-27 10:40:28

+1

用户不应包含密码IMO,既不以明文形式也不以散列形式。 – Gordon 2011-04-27 10:51:57

+0

也是如此,凭证可以单独存储。我的例子来自我发现在一些CMS数据库模式中很常见的例子。 – akamike 2011-04-27 10:57:12

0

你是对的,因为在一个人看电影时,一个人认证自己并不常见。在你与同事的争论中,你可能想要概括一下:

谁负责认证 用户?

这是一个问题,你可以问问自己,每当你似乎卡住了设计问题。我并不是说这是一个能够回答你所有问题的规则,但它在很多情况下都能清除困扰的问题,你的问题就是一个很好的例子。

您可能还需要阅读这样的文字:

http://lizkeogh.com/2009/07/01/pixie-driven-development/