2011-04-27 45 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/