2015-10-22 17 views
8

Il mio finder da Auth ha le condizioni che ho bisogno di accedere a $this->request ma non ho accesso per quello su UsersTable.Passare dati aggiuntivi all'autore del finder

AppController :: inizializzo

$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; 
} 

ho bisogno di passare un dati aggiuntivi fom AppController a finderauth dal momento che non hanno accesso al $this->request->data su UsersTable.

Aggiornamento

La gente dice sui commenti che è una cattiva progettazione in modo vi spiegherò esattamente quello che mi serve.

Ho una tabella users ma ogni utente appartiene a un gym. Il username(email) è univoco solo per un particolare gym in modo da poter avere un [email protected] da gym_id 1 e un altro [email protected] da gym_id 2. Nella pagina di accesso, ho il gym_slug da comunicare a auth finder a quale gym l'utente username appartiene.

+0

Questo suona forse come un cattivo design per me, potresti mostrare quello che volevi trasmettere? Deve essere possibile in qualche modo come un comportamento :-) – Spriz

+0

Sto passando una slug da palestra in url quindi ho bisogno di ottenere l'ID della palestra basata su quel slug da filtrare a find dell'utente perché ho 'gym_id' a tabella 'utenti'. Posso accedere allo slug con 'this-> request-> params ['gym_slug]' ma non lo accetto a 'UsersTable' –

+0

Abbiamo bisogno di un po' più di informazioni per andare avanti qui. Sembra sia dalla domanda che dai commenti che forse stai autenticando un utente e poi provi a reindirizzarlo alla pagina della loro palestra? Modifica la tua domanda e fornisci esattamente ciò che stai facendo e perché.Non menzioni la palestra fino al commento sopra e sono curioso del motivo per cui avresti bisogno dei dati della richiesta per reindirizzare (se è anche quello che stai facendo) dato che hai il gym_id memorizzato nello stesso tavolo. –

risposta

2

Per quanto ne so, non c'è modo di farlo passando alla configurazione in 3.1. Questa potrebbe essere una buona idea per inviare l'hub git cakephp come richiesta di una funzione.

Ci sono modi per farlo creando un nuovo oggetto di autenticazione che estende l'autenticazione di base e quindi sovrascrive _findUser e _query. Qualcosa di simile a questo:

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; 
} 
} 

Per ulteriori informazioni vedere questo: Creating Custom Authentication Objects

+1

Ha funzionato con me, è un peccato che non potessi darti la taglia prima che scada –

+0

È abbastanza buono! Qualsiasi cosa per aiutare un collega sviluppatore! – chrisShick

1

So che questa è una vecchia questione, ma ho pensato di postare il cercatore che sto usando in una delle nostre applicazioni SaaS costruita su CakePHP 3 Segue ESSENZIALE, ecc. Probabilmente no. Per dire che tutto può essere fatto in modo X o Y ..... devi sempre piegare le regole. In questo caso, a seconda del URL (xdomain.com o ydomain.com) la nostra app capisce chi è il cliente e cambia layout ecc Inoltre l'utente in base è legato a e-mail & site_id molto simile alla vostra

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; 
} 

Comunque spero che aiuti qualcuno