Как Вы сделали авторизацию?

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Как Вы сделали авторизацию?

Сообщение Bloom »

Я создал тестовое приложение. Делал все как показано в офф. руководстве и менял всю авторизацию на популярные расширения yii-user и yii-rights.

Мне категорически непонятна ситуация, когда после авторизации пользователя (как с вводом данных, так и через cookie) - id, name и states записываются в сессию и более не обновляются до последующей авторизации.
Я не понимаю логики данного метода. Получается, что если я в процессе работы изменю роль пользователя или забаню его - оно применится только после повторного входа пользователя в систему, а не сразу.

Как Вы решили данный вопрос, и решали ли вообще? Единственное удобство, которое я наблюдаю в данном методе, это нет постоянных запросов в базу данных для аутентификации пользователя. Если проект имеет много пользователей - это плюсег, но он никак не сравнится с минусом - моментальный бан пользователя и изменение прав.
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Как Вы сделали авторизацию?

Сообщение lancecoder »

если бан - logout
если сменили роль, то она как правило не хранится в сессии, а в бд, тогда она применится при первой выборке, т.е. после след. обращения к сайту
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Как Вы сделали авторизацию?

Сообщение Bloom »

Внезапно родилась идея.
В yii-user есть отличный пример.

Код: Выделить всё

public function accessRules()
    {
        return array(
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions'=>array('admin','delete','create','update','view'),
                'users'=>UserModule::getAdmins(),
            ),
            array('deny',  // deny all users
                'users'=>array('*'),
            ),
        );
    }
т.е. перед тем, как будет выполнено действие, требующее каких-то прав - надо сделать выборку из базы всех админов. Если данный пользователь не попадет под этот список - доступ будет запрещен. Т.е. если даже пользователь был админом, но его заблокировали или изменили права - он хоть и останется (якобы) залогинен, но не получит прав доступа к этому действию.

Такой вопрос - используя CPhpAuthManager - возможно ли организовать такую проверку, чтобы для действий требующих прав больше чем guest - обновлять регистрационные данные пользователя?
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Как Вы сделали авторизацию?

Сообщение Bloom »

lancecoder писал(а):если бан - logout
если сменили роль, то она как правило не хранится в сессии, а в бд, тогда она применится при первой выборке, т.е. после след. обращения к сайту
Я в сессии храню только id name и hash, который так-же хранится в куках для входа через куки.
В каком месте кода вы проверяете, что пользователь оказался забаненым? Т.е. при каждом обращении пользователя вы заново проходите операцию CWebUser::login()?
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Как Вы сделали авторизацию?

Сообщение lancecoder »

ууу, да вы не представляете общую картину авторизации через куки, почитайте мануал
п.с. beforeLogin
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Как Вы сделали авторизацию?

Сообщение Bloom »

Код: Выделить всё

        protected function beforeLogin($id, $states, $fromCookie) {
                if (parent::beforeLogin($id, $states, $fromCookie)) {
                        if ($fromCookie) {
                                //Находим в базе пользователя по ID
                                $user = User::model()->active()->findByPk($id);
                                if ($user === null)
                                        return false;
                                else if ($user->hash !== $states["auth"])
                                        return false;
                                else {
                                        return true;
                                }
                        } else {
                                return true;
                        }
                } else {
                        return false;
                };
        } 
от такая портянка у меня в классе WebUser, который расширяет CWebUser. В конфиге так-же все прописано.
Но оно срабатывает только после окончании срока действии сессии. This method is called before logging in a user. For example, when the login is cookie-based, you may want to verify that the user ID together with a random token in the states can be found in the database. Что собственно я и сделал.
Я проверял удалением из куков PHPSESSID. Оно срабатывает только тогда. Логер подтверждает выполнение данного действия созданным запросом. Соответственно создается новая сессия и повторная авторизация не требуется.
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Как Вы сделали авторизацию?

Сообщение lancecoder »

ну добавь еще в init
if (!Yii::app()->getUser()->getIsGuest()){

}
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Как Вы сделали авторизацию?

Сообщение lancecoder »

проверяй там статус, если забанен, то на логаут его редиректь
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Как Вы сделали авторизацию?

Сообщение Bloom »

Код: Выделить всё

public function init() {
                if (!Yii::app()->user->isGuest) {
                        //Ищем активного пользователя где id совпадает с user->id
                        $user = User::model()->active()->findByPk(Yii::app()->user->id);
                        if ($user === null) {
                                Yii::app()->user->logout();
                                $this->redirect(Yii::app()->homeUrl);
                        }
                }
        } 
Я правильно сделал?)) если да - закрываем тему.
Аватара пользователя
maleks
Сообщения: 1994
Зарегистрирован: 2012.12.26, 12:56

Re: Как Вы сделали авторизацию?

Сообщение maleks »

подпишусь, т.к. скоро мне это предстоит.
Аватара пользователя
anton44eg
Сообщения: 2716
Зарегистрирован: 2012.01.25, 13:37
Откуда: Киев

Re: Как Вы сделали авторизацию?

Сообщение anton44eg »

я делаю похоже, только еще кеширую
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Как Вы сделали авторизацию?

Сообщение Bloom »

А подробнее? Что кешируете?
Вопрос как раз в том, как люди организовывают авторизацию и аутентификацию пользователей на сайтах.
Если есть более безопасные методы или более гибкие в плане поддержки - делитесь)) т.к. в официальном руководстве тема затрагивается поверхностно и с плохими примерами.
Может кто-то использует расширения, кто-то использует OpenID или привязку к другим сервисам?
Встроенная в фрэймворк система сложна для первого понимания.

Лично мне было бы удобно в init засунуть не только проверку на статус пользователя, но и присваивание всех (безопасных) значений из базы user в некоторое свойство класса user(ошибка, класса WebUser) так, чтобы они были доступны в любом месте кода (например: yii::app()->user->base['значение']), но не появлялись в сессии и в куках.
Это удобно тем, что иногда в коде придется обращаться к данным свойствам городя новый запрос, который уже был выполнен в init.
Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: Как Вы сделали авторизацию?

Сообщение lancecoder »

ну так а модель присвоить это разве не безопасные аттрибуты пользователя?
Аватара пользователя
anton44eg
Сообщения: 2716
Зарегистрирован: 2012.01.25, 13:37
Откуда: Киев

Re: Как Вы сделали авторизацию?

Сообщение anton44eg »

Код: Выделить всё

protected  function beforeAction($action)
    {
        if(parent::beforeAction($action))
        {
            if(!Yii::app()->user->isGuest)
            {
                $enabled = Yii::app()->cache->get('user_enabled:' . Yii::app()->user->id);
                if($enabled === false)
                {
                    $enabled = Yii::app()->db->createCommand('SELECT enabled FROM user WHERE id = ' . Yii::app()->user->id)->queryScalar();
                    Yii::app()->cache->set('user_enabled:' . Yii::app()->user->id, $enabled, 360);
                }
                if(!$enabled)
                {
                    Yii::app()->user->logout();
                    throw new CHttpException(403);
                }
            }
        }
        return true;
    } 
Bloom
Сообщения: 313
Зарегистрирован: 2013.02.25, 12:57

Re: Как Вы сделали авторизацию?

Сообщение Bloom »

Ммм... фирсштейн, куда удобнее!!
Аватара пользователя
anton44eg
Сообщения: 2716
Зарегистрирован: 2012.01.25, 13:37
Откуда: Киев

Re: Как Вы сделали авторизацию?

Сообщение anton44eg »

и, желательно, не забывать сбрасывать (обновлять) кеш при бане юзера
Ответить