来自Auth的我的查找器有条件我需要访问$this->请求,但我无权访问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; }
我需要将一个额外的数据从AppController传递给finder auth,因为我没有访问UsersTable上的$this-> request->数据.
更新
人们在评论中说这是一个糟糕的设计,所以我会准确地解释我需要什么.
我有一个表用户,但每个用户都属于健身房.
用户名(电子邮件)仅对特定健身房是唯一的,因此我可以从gym_id 1获得example@domain.com,从gym_id 2获得另一个example@domain.com.
在登录页面上,我有gym_slug告诉auth finder wich gym我所提供的用户名.
据我所知,没有办法将它传递到3.1中的配置.这可能是一个好主意在cakePHP git hub上提交作为功能请求.
有一些方法可以通过创建一个新的身份验证对象来扩展基本身份验证,然后覆盖_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