2015-10-22 51 views
8

我的發現者從Auth有條件,我需要訪問$this->request,但我不能訪問UsersTable傳遞額外數據給發現者驗證

的AppController ::初始化

$this->loadComponent('Auth', [ 
     'authenticate' => [ 
      'Form' => [ 
       'finder' => 'auth', 
      ] 
     ] 
    ]); 

UsersTable

public function findAuth(Query $query, array $options) 
{ 
    $query 
     ->select([ 
      'Users.id', 
      'Users.name', 
      'Users.username', 
      'Users.password', 
     ]) 
     ->where(['Users.is_active' => true]); // If i had access to extra data passed I would use here. 

    return $query; 
} 

我需要傳遞一個額外的數據FOM AppControllerfinderauth因爲我沒有上UsersTable存取權限$this->request->data

更新

人們都在說上評論這是一個糟糕的設計,所以我會正是我需要解釋一下。

我有一個表users但每個用戶都屬於gymusername(email)只對特定的gym唯一,所以我可以有[email protected]gym_id 1和另一個[email protected]gym_id 2。 在登錄頁面我有gym_slug告訴auth finder至極gym我提供的用戶username屬於。

+0

這聽起來像是對我可能是不好的設計,你能顯示你想傳遞什麼?它必須是可能的作爲一種行爲,雖然:-) – Spriz

+0

我通過一個健身房slu at在URL,所以我需要得到基於該slu的健身房ID過濾用戶查找,因爲我有'gym_id'在'用戶'表。我可以通過'this-> request-> params ['gym_slug]'訪問slug,但是我沒有在'UsersTable'上使用accesa。 –

+0

我們需要更多的信息繼續下去。從問題和評論中都可以聽到,也許你正在驗證用戶,然後試圖將他們重定向到他們的健身房頁面?編輯你的問題,並提供你正在做什麼以及爲什麼。你直到上面的評論才提到健身房,我很好奇爲什麼你需要請求數據重定向(如果這就是你正在做的),因爲你已將gym_id存儲在同一個表中。 –

回答

2

據我所知,沒有辦法通過將它傳遞到3.1中的配置。作爲一個功能請求,這可能是一個好主意在cakephp git集線器上提交。

有辦法通過創建一個新的身份驗證對象來擴展基本身份驗證,然後重寫_findUser和_query。事情是這樣的:

class GymFormAuthenticate extends BaseAuthenticate 
{ 

/** 
    * Checks the fields to ensure they are supplied. 
    * 
    * @param \Cake\Network\Request $request The request that contains login information. 
    * @param array $fields The fields to be checked. 
    * @return bool False if the fields have not been supplied. True if they exist. 
    */ 
protected function _checkFields(Request $request, array $fields) 
{ 
    foreach ([$fields['username'], $fields['password'], $fields['gym']] as $field) { 
     $value = $request->data($field); 
     if (empty($value) || !is_string($value)) { 
      return false; 
     } 
    } 
    return true; 
} 

/** 
    * Authenticates the identity contained in a request. Will use the `config.userModel`, and `config.fields` 
    * to find POST data that is used to find a matching record in the `config.userModel`. Will return false if 
    * there is no post data, either username or password is missing, or if the scope conditions have not been met. 
    * 
    * @param \Cake\Network\Request $request The request that contains login information. 
    * @param \Cake\Network\Response $response Unused response object. 
    * @return mixed False on login failure. An array of User data on success. 
    */ 
public function authenticate(Request $request, Response $response) 
{ 
    $fields = $this->_config['fields']; 
    if (!$this->_checkFields($request, $fields)) { 
     return false; 
    } 
    return $this->_findUser(
     $request->data[$fields['username']], 
     $request->data[$fields['password']], 
     $request->data[$fields['gym']], 
    ); 
} 

/** 
    * Find a user record using the username,password,gym provided. 
    * 
    * Input passwords will be hashed even when a user doesn't exist. This 
    * helps mitigate timing attacks that are attempting to find valid usernames. 
    * 
    * @param string $username The username/identifier. 
    * @param string|null $password The password, if not provided password checking is skipped 
    * and result of find is returned. 
    * @return bool|array Either false on failure, or an array of user data. 
    */ 
protected function _findUser($username, $password = null, $gym = null) 
{ 
    $result = $this->_query($username, $gym)->first(); 

    if (empty($result)) { 
     return false; 
    } 

    if ($password !== null) { 
     $hasher = $this->passwordHasher(); 
     $hashedPassword = $result->get($this->_config['fields']['password']); 
     if (!$hasher->check($password, $hashedPassword)) { 
      return false; 
     } 

     $this->_needsPasswordRehash = $hasher->needsRehash($hashedPassword); 
     $result->unsetProperty($this->_config['fields']['password']); 
    } 

    return $result->toArray(); 
} 

/** 
    * Get query object for fetching user from database. 
    * 
    * @param string $username The username/identifier. 
    * @return \Cake\ORM\Query 
    */ 
protected function _query($username, $gym) 
{ 
    $config = $this->_config; 
    $table = TableRegistryget($config['userModel']); 

    $options = [ 
     'conditions' => [$table->aliasField($config['fields']['username']) => $username, 'gym' => $gym] 
    ]; 

    if (!empty($config['scope'])) { 
     $options['conditions'] = array_merge($options['conditions'], $config['scope']); 
    } 
    if (!empty($config['contain'])) { 
     $options['contain'] = $config['contain']; 
    } 

    $query = $table->find($config['finder'], $options); 

    return $query; 
} 
} 

欲瞭解更多信息,請參閱本:Creating Custom Authentication Objects

+1

工作對我來說,它是一個恥辱我不能給你的賞金在它到期前 –

+0

這是非常好的!任何事情都可以幫助開發人員! – chrisShick

1

我知道這是一個老問題,但我想我會後我使用內置的CakePHP的3我們的SaaS應用程序的一個取景器它是否遵循DRY等可能不是。說一切都可以做X或Y的方式......你總是不得不彎曲規則。在這種情況下,根據URL(xdomain.com或ydomain.com)我們的應用程序計算出誰是客戶,改變佈局等,還可根據被綁定到電子郵件&用戶SITE_ID很像你

public function findAuth(\Cake\ORM\Query $query, array $options) { 
    $query 
      ->select([ 
       'Users.id', 
       'Users.email', 
       'Users.password', 
       'Users.site_id', 
       'Users.firstname', 
       'Users.lastname']) 
      ->where([ 
       'Users.active' => 1, 
       'Users.site_id'=> \Cake\Core\Configure::read('site_id') 
      ]); 

    return $query; 
} 

不管怎麼說希望它可以幫助別人

相關問題