Компонент cakephp auth с двумя сеансами моделей
У меня есть два приложения cakephp2, работающих в одной базе данных, но имеющие разные таблицы Auth и разные значения this this > Auth- > userModel.
Аутентификация работает хорошо, и пользователи из одного приложения не могут войти в другой.
НО.. поскольку приложения используют один и тот же файл cookie сеанса CAKEPHP, это происходит:
когда пользователь из приложения "один" входит в систему, он может получить доступ к любому защищенному от защиты действию в приложении "два"!
Я, вероятно, буду использовать разные роли пользователей и имена файлов cookie.
Но все же, почему компонент Auth игнорирует параметры Auth- > userModel при проверке сеанса? Есть ли способ настроить его для работы в этой ситуации?
Заранее благодарим за любые предложения.
Ответы
Ответ 1
Если не указано иное, AuthComponent будет записывать аутентифицированную запись пользователя в ключ сеанса Auth.User
в CakePHP 2. Но его можно изменить:
AuthComponent:: sessionKey
Имя ключа сеанса, в котором хранится запись текущего пользователя. Если это не указано, это будет "Auth.User".
(В CakePHP 1.3 это было другое: Auth.{$userModel name}
)
Итак, если ваши приложения совместно используют сеанс, который они выполняют, если имя файла cookie и Security.salt
совпадают, запись в журнале будет общедоступной.
Есть две возможности решить эту проблему:
Отделить логины
Просто установите другую AuthComponent::sessionKey
для двух моделей. Это позволит им сохранить зарегистрированного пользователя отдельно
Отделить сеансы
Настройте разные имена файлов cookie и Соли для обоих приложений, поэтому их сеансы не могут переопределять друг друга. Это, вероятно, более чистое решение, поскольку оно также покрывает риск использования других ключей сеанса.
Ответ 2
У меня есть аналогичная проблема, поэтому я начал щедрость по этому вопросу. В основном у меня есть публичная сторона приложения, которая позволяет пользователям входить в систему из одной таблицы и административной части приложения, что позволяет администраторам входить в систему с использованием другой таблицы. Мой AppController выглядит примерно так:
public $components = array(
'Session',
'Auth' => array(
'autoRedirect' => false,
'authenticate' => array(
'Form' => array(
'userModel' => 'User'
)
),
'loginAction' => array('controller' => 'users', 'action' => 'login'),
'loginRedirect' => array('controller' => 'users', 'action' => 'overview'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'loggedout')
)
);
и у меня есть другой AdminController, где у меня есть это:
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'CustomForm' => array(
'userModel' => 'Admin'
)
),
'loginAction' => array('controller' => 'admin', 'action' => 'login'),
'loginRedirect' => array('controller' => 'admin', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'home', 'action' => 'index')
)
);
Но, как упоминалось в этом вопросе, сеансы от двух не ладят друг с другом и перезаписывают друг друга. Какой лучший способ преодолеть это?
Ответ 3
Разверните обработчик сеанса Model/Datasource/Session/DatabaseSession.php с чем-то вроде MyDatabaseSession и перезапишите методы записи и чтения. Возможно, просто скопируйте существующий код обоих методов и добавьте что-то вроде
'app_id' = > Configure:: read ('App.appId')
для условий read() и сделать то же самое в методе записи. И не забудьте добавить поле к вашей схеме базы данных сеансов и настроить сеанс для использования вашего обработчика.
<?php
App::uses('DatabaseSession', 'Model/Datasource/Session');
class ExtendedDatabaseSession extends DatabaseSession {
public function read($id) {
$row = $this->_model->find('first', array(
'conditions' => array(
'app_id' => Configure::read('App.appId'),
$this->_model->primaryKey => $id)));
if (empty($row[$this->_model->alias]['data'])) {
return false;
}
return $row[$this->_model->alias]['data'];
}
public function write($id, $data) {
if (!$id) {
return false;
}
$expires = time() + $this->_timeout;
$record = compact('id', 'data', 'expires');
$record[$this->_model->primaryKey] = $id;
$record['app_id'] = Configure::read('App.appId');
return $this->_model->save($record);
}
}
Я не знаю вашего приложения, так что вы пишете идентификатор приложения для данных конфигурации, зависит от вас, bootstrap или beforeFilter(). Вы должны добавить его, прежде чем инициализировать сеанс, я думаю, или вам нужно будет перезапустить сеанс или что-то еще. Я оставляю это для вас, чтобы посмотреть в нужную точку.:)