Cakephp Auth с несколькими таблицами "Пользователи"
Я хотел бы знать, как иметь дело только с одним процессом аутентификации и "пользователями" в нескольких таблицах. У меня есть таблица 4 Users: пользователи, администраторы, художники, teamadmins, у которых есть определенные поля, но я хотел бы, чтобы все эти пользователи могли подключаться только через одну форму на главной странице и перенаправляться после этого в свои специальные информационные панели.
Я думаю, что перенаправления не должны быть проблемой, и некоторые добавленные маршруты должны работать, но я действительно не знаю, где искать/начинать все это.
Приветствия,
Николя.
EDIT: здесь окончательное решение (спасибо deizel)
App::import('Component', 'Auth');
class SiteAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
$models = array('User', 'Admin', 'Artist');
foreach ($models as $model) {
$this->userModel = $model; // switch model
$this->params["data"][$model] = $this->params["data"]["User"]; // switch model in params/data too
$result = parent::identify($this->params["data"][$model], $conditions); // let cake do its thing
if ($result) {
return $result; // login success
}
}
return null; // login failure
}
}
Ответы
Ответ 1
CakePHP AuthComponent
поддерживает аутентификацию только по одной модели "Пользователь". Модель выбирается путем установки свойства Auth::userModel
, но оно принимает только строку, а не массив моделей.
Вы можете переключить userModel
на лету с помощью следующего кода, но для этого вам необходимо заранее знать, к какой модели нужно переключиться (например, ваши пользователи должны выбрать тип своей учетной записи из раскрывающегося списка):
public function beforeFilter() {
if (isset($this->data['User']['model'])) {
$this->Auth->userModel = $this->data['User']['model'];
}
}
Вы можете расширить ядро AuthComponent
, чтобы добавить нужные функции, перезаписав метод AuthComponent::identify()
, чтобы он переходил на и попытки аутентификации с каждой моделью:
App::import('Component', 'AuthComponent');
class AppAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
$models = array('User', 'Admin', 'Artist', 'TeamAdmin');
foreach ($models as $model) {
$this->userModel = $model; // switch model
$result = parent::identify($user, $conditions); // let cake do it thing
if ($result) {
return $result; // login success
}
}
return null; // login failure
}
}
Вам нужно будет заменить вхождения Auth
в приложении с помощью AppAuth
, чтобы использовать расширенный AuthComponent, если вы не используете этот трюк.
Ответ 2
В то время как раздражает, я думаю, что лучшим решением, вероятно, будет использование Cake, встроенного в поддержку ACL (см. http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html).
Если вы выполняете аутентификацию, как вы говорите, вы должны отслеживать разрешения в своем коде контроллера, проверяя, что такое userModel. Если вы используете список управления доступом, дерево разрешений уже будет существовать в базе данных, что должно значительно упростить ваш код и сделать его более модульным.
Это также означает реструктуризацию вашей модели данных, чтобы иметь таблицу пользователей и таблицу групп вместо классов сущности для каждого типа пользователей.
Я просто прошел процесс сам по себе...: (
Ответ 3
это также возможность
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->authenticate = array(
AuthComponent::ALL => array('userModel' => 'AnotherModel'),
'Form',
'Basic'
);
}
Ответ 4
Вот окончательное решение, предложенное deizel и измененное Николасом:
App::import('Component', 'Auth');
class SiteAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
$models = array('User', 'Admin', 'Artist');
foreach ($models as $model) {
$this->userModel = $model; // switch model
$this->params["data"][$model] = $this->params["data"]["User"]; // switch model in params/data too
$result = parent::identify($this->params["data"][$model], $conditions); // let cake do its thing
if ($result) {
return $result; // login success
}
}
return null; // login failure
}
}