2013-11-04 114 views
3

我有一個關於存儲相當複雜的應用程序邏輯的最佳位置的問題。我應該在哪裏放置登錄功能的應用程序邏輯?

說我想讓用戶登錄到網站。登錄的過程應該包括以下步驟:

  1. 從表單字段,哈希用戶的電子郵件
  2. 查找用戶的電子郵件散在身份驗證表,以確保用戶 存在(AUTH錶店只有加密的電子郵件,郵件亂碼,USER_ID, 和密碼哈希)
  3. 如果發現用戶,然後驗證其密碼
  4. 重新生成會話ID
  5. 在數據庫中存儲的新會話

使用數據映射器模式,我有參與這個過程

/User/ 
- User.php 
- UserMapper.php 

/Auth/ 
- Auth.php 
- AuthMapper.php 

/Session/ 
- Session.php 
- SessionMapper.php 

因此它會記錄用戶會是這個樣子的函數以下三種模式:

function login($email, $password) 
{ 
    $security = new \Lib\Security; 
    $authMapper = new \Models\Auth\AuthMapper($this->db); 
    $userMapper = new \Models\User\UserMapper($this->db); 
    $session = new \Models\Session\Session; 
    $sessionMapper = new \Models\Session\SessionMapper($this->db); 

    $email_hash = $security->simpleHash($email); 

    if (!$auth = $authMapper->fetchWhere('email_hash', $email_hash)) 
    { 
     echo 'User doesnt exist'; 
     return; 
    } 

    if (!$auth->verifyPassword($password)) 
    { 
     echo 'Password not correct'; 
     return; 
    } 

    $user = $userMapper->fetchById($auth->user_id); 

    $session->createUserSession($user); 

    $sessionMapper->save($session); 
} 

這裏有幾個問題。首先是缺乏依賴注入。第二個是,這是一個繁瑣的代碼塊來使用我可能想提供登錄功能的每個地方。

那麼這個邏輯應該在哪裏存在?在控制器中?在用戶域對象?在Auth域對象中?這似乎是一種循環 - 數據映射器的全部要點是,域對象不處理連本身的持久性,更不用說OTHER對象了....如果它被放置在用戶或Auth服務層中/用戶/或/ Auth /模型?

對於這種事情的最佳實踐,我有點失落。

另外請記住,我是爲了學習的目的,所以我不想只使用像Symfony這樣的東西。

回答

0

爲了回答我自己的問題,我已經決定創建一個AccountController接口作爲構造函數參數的最佳位置是AccountController

的的AccountController則是這樣的:

namespace App\Controllers; 

class AccountController 
{ 
    protected $LoginHandler; 

    public function __construct(\Framework\Interfaces\LoginHandlerInterface $LoginHandler) 
    { 
     $this->LoginHandler = $LoginHandler; 
    } 

    public function login() 
    { 
     if (/* ... form validation stuff ... */) 
     { 
      try 
      { 
       $this->LoginHandler->login($email, $password); 
      } 
      catch (\Framework\Exceptions\Login $e) 
      { 
       // Assign login errors to template etc... 
      } 
     } 
    } 
} 

然後取其LoginHandler我最終使用,有需要做所有的日誌中(查找用戶,驗證密碼的一切,更新會話等等)。這使我的AccountController乾淨,靈活,可測試。

我通過自動解析構造函數依賴項的IoC容器中的配置注入了所需的LoginHandler(和RegistrationHandler,這裏我沒有示出)。

-1

如果登錄失敗,Auth應該處理返回false, 如果是true,則執行會話的邏輯並返回true。

所以在你的控制器,你會做這樣的事情,如果(Auth->登錄($電子郵件,$密碼))

PS:對於這種類型的工作流程,我更喜歡使用Singleton模式(壽它破壞單位測試),但我認爲它會更適合你。

+0

如果投了票,請讓我知道爲什麼!乾杯 –

相關問題