Authentication 将额外数据传递给finder auth
来自Authentication 将额外数据传递给finder auth,authentication,orm,cakephp-3.0,Authentication,Orm,Cakephp 3.0,来自Auth的我的查找器具有我需要访问$this->request的条件,但我无法在UsersTable上访问该条件 AppController::初始化 $this->loadComponent('Auth', [ 'authenticate' => [ 'Form' => [ 'finder' => 'auth', ] ] ]); public f
Auth
的我的查找器具有我需要访问$this->request
的条件,但我无法在UsersTable
上访问该条件
AppController::初始化
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'finder' => 'auth',
]
]
]);
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;
}
UsersTable
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'finder' => 'auth',
]
]
]);
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
,因为我无法访问$this->request->data
上的UsersTable
更新
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'finder' => 'auth',
]
]
]);
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;
}
人们在评论中说这是一个糟糕的设计,所以我会准确地解释我需要什么
我有一个表用户
,但每个用户都属于健身房
。
用户名(电子邮件)
仅对特定的健身房是唯一的,因此我可以拥有example@domain.com
来自健身房id 1
和另一个example@domain.com
来自健身房id 2
。
在登录页面上,我有gym\u slug
告诉auth finder
我提供的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;
}
}
有关更多信息,请参见:我知道这是一个老问题,但我想我会发布我在基于Cakephp 3构建的SaaS应用程序中使用的finder。它是否遵循干燥等可能不。说什么都可以用X或Y的方式来做。。。。。你总是要违反规则。在这种情况下,根据URL(xdomain.com或ydomain.com),我们的应用程序会找出客户是谁,并更改布局等。此外,基于用户的应用程序与您的电子邮件和站点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;
}
无论如何,希望它能帮助别人对我来说,这听起来可能是个糟糕的设计,你能展示一下你想要传递的东西吗?这在某种程度上可能是一种行为:-)我在url上传递了一个健身房段塞,因此我需要根据该段塞获取健身房ID,以便在用户查找时进行筛选,因为我在用户
表中有健身房ID
。我可以通过this->request->params['gym\u slug]
访问slug,但是我在UsersTable
上没有权限访问这个slug,我们需要更多的信息。从问题和评论中都可以看出,你可能正在验证一个用户,然后试图将其重定向到健身房的页面?编辑你的问题,准确地提供你正在做的事情和原因。直到上面的评论,你才提到健身房,我很好奇为什么你需要请求数据重定向(如果你正在做的话)因为您的gym\u id存储在同一个表中。我从来没有提到过重定向
,我只需要finder
上的gym\u slug
在上用作条件
,就这么简单。我将编辑和解释多一点。对我来说,很遗憾我不能在赏金到期之前给你它是很好的!任何可以帮助开发人员的东西!