Подтвердить что ты не робот

Компонент cakephp auth с двумя сеансами моделей

У меня есть два приложения cakephp2, работающих в одной базе данных, но имеющие разные таблицы Auth и разные значения this this > Auth- > userModel. Аутентификация работает хорошо, и пользователи из одного приложения не могут войти в другой.

НО.. поскольку приложения используют один и тот же файл cookie сеанса CAKEPHP, это происходит: когда пользователь из приложения "один" входит в систему, он может получить доступ к любому защищенному от защиты действию в приложении "два"!

Я, вероятно, буду использовать разные роли пользователей и имена файлов cookie. Но все же, почему компонент Auth игнорирует параметры Auth- > userModel при проверке сеанса? Есть ли способ настроить его для работы в этой ситуации?

Заранее благодарим за любые предложения.

4b9b3361

Ответ 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(). Вы должны добавить его, прежде чем инициализировать сеанс, я думаю, или вам нужно будет перезапустить сеанс или что-то еще. Я оставляю это для вас, чтобы посмотреть в нужную точку.:)