Авторизация с помощью куки

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Аватара пользователя
Elfer
Сообщения: 132
Зарегистрирован: 2012.06.07, 16:09
Откуда: Беларусь, Лида
Контактная информация:

Авторизация с помощью куки

Сообщение Elfer »

Всем привет. У меня Yii 1.1.15. Столкнулся с проблемой - не срабатывает авторизацию через куку. Т.е. посетитель авторизовался и является авторизованным, пока сессия не закончилась либо не закрыл браузер. Но мне нужно, чтобы в этом случае авторизация все равно сохранялась. Для этого в Yii предусмотрено свойство компонента User allowAutoLogin = true.
В конфиге у меня прописано:

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

'user'=>array(
    'class' => 'WebUser',
    // enable cookie-based authentication
    'allowAutoLogin'=>true,
), 
Когда запускаю функцию Yii::app()->user->login($identity, 604800) устанавливаю второй параметр 604800. Т.е. все это говорит о том, что авторизация должна сохраняться в куке на неделю, а не в сессии. Но увы!

Ниже размещу коды, вы можете в коде увидеть сокращения (функции), которые я использую, но можете догадаться, что они означают, такие как user(), controller() и т.д. На всякий случай скину парочку из них, чтобы было понятнее:

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

function controller() {
    return Yii::app()->controller;
}

function setState($key, $value, $defaultValue = null) {
    return Yii::app()->user->setState($key, $value, $defaultValue);
}

function getState($key, $defaultValue = null) {
    return Yii::app()->user->getState($key, $defaultValue);
}

function user() {
    return Yii::app()->user;
}

function isGuest() {
    return Yii::app()->user->isGuest;
}
components/UserIdentity.php:

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

class UserIdentity extends CUserIdentity {
    private $_id;
    const ERROR_NONE = 0;
    const ERROR_USERNAME_INVALID = 1;
    const ERROR_PASSWORD_INVALID = 2;
    const ERROR_DELETED = 3;
    const ERROR_BANNED = 4;
    const ERROR_INACTIVE = 5;

    public function authenticate() {
        $user = User::model()->findByAttributes(array('username'=>$this->username));
        if ($user === null)
            $this->errorCode = self::ERROR_USERNAME_INVALID;
        elseif (!checkPassword($user->password, $this->password))
            $this->errorCode = self::ERROR_PASSWORD_INVALID;
        elseif (!$user->public and $user->deleted)
            $this->errorCode = self::ERROR_DELETED;
        elseif ($user->ban)
            $this->errorCode = self::ERROR_BANNED;
        elseif (!$user->public)
            $this->errorCode = self::ERROR_INACTIVE;
        else {
            $this->_id = $user->id;
            $this->errorCode = self::ERROR_NONE;
        }
        return !$this->errorCode;
    }
    
    public function getId() {
        return $this->_id;
    }
}
components/WebUser.php:

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

class WebUser extends CWebUser {
    private $_model = null;
    
    public function init() {
        parent::init();
        if (preg_match("/^admin\//", Yii::app()->controller->id)) {
            $this->stateKeyPrefix = md5('Admin');
            $this->loginUrl = '/admin';
        } else {
            $this->stateKeyPrefix = md5('User');
            $this->loginUrl = '/site/auth';
        }
    }
    
    public function getRole() {
        if ($user = $this->getModel()){
            if (isset($user->type))
                return $user->type;
            else return null;
        }
    }
    
    public function data($attr) {
        if ($user = $this->getModel() and isset($user->$attr)){
            return $user->$attr;
        }
    }

    private function getModel(){
        if (!$this->isGuest && $this->_model === null){
            if (preg_match("/^admin\//", Yii::app()->controller->id))
                $this->_model = Admin::model()->findByPk($this->id);
            else {
                $this->_model = User::model()->findByAttributes(array('id'=>$this->id, 'public'=>1));
                if ($this->_model === null)
                    Yii::app()->user->logout();
            }
        }
        return $this->_model;
    }
}
models/UserLoginForm.php:

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

class UserLoginForm extends CFormModel {
    public $username;
    public $password;
    public $rememberMe = false;
    public $verifyCode;

    private $_identity;
 
    public function rules() {
        $rules = array(
            array('username, password', 'required'),
            array('password', 'length', 'min'=>User::$minPassword, 'max'=>User::$maxPassword),
            array('username', 'length', 'min'=>User::$minUsername, 'max'=>User::$maxUsername),
            array('rememberMe', 'boolean'),
        );
        if (getState('authUserNums', 0) >= controller()->params['authUserCaptchaNumber'])
            $rules[] = array('verifyCode', 'captcha');
        return $rules;
    }
    
    public function attributeLabels() {
        return array(
            'username' => 'Логин',
            'password' => 'Пароль',
            'rememberMe' => 'Запомнить',
            'verifyCode' => 'Код проверки',
        );
    }

    public function login() {
        if ($this->_identity === null) {
            $this->_identity = new UserIdentity($this->username, $this->password);
            $this->_identity->authenticate();
        }
        if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) {
            setState('authUserNums', 0);
            $duration = $this->rememberMe ? 604800 : 0; // 7 days
            user()->login($this->_identity, $duration);
            return true;
        } else {
            $authNums = getState('authUserNums', 0);
            $authNums++;
            $error = '';
            setState('authUserNums', $authNums);
            if ($this->_identity->errorCode === UserIdentity::ERROR_USERNAME_INVALID or $this->_identity->errorCode === UserIdentity::ERROR_PASSWORD_INVALID)
                $error = 'Неверный логин либо пароль.';
            elseif ($this->_identity->errorCode === UserIdentity::ERROR_DELETED)
                $error = 'Ваш аккаунт удалён.';
            elseif ($this->_identity->errorCode === UserIdentity::ERROR_BANNED) {
                $user = User::model()->findByAttributes(array('username'=>$this->username));
                $error = 'Ваш аккаунт забанен. Причина: '.$user->ban;
            } elseif ($this->_identity->errorCode === UserIdentity::ERROR_INACTIVE)
                $error = 'Ваш аккаунт неактивен.';
            $this->addError('', $error);
            return false;
        }

    }
}
Ну и сам экшен контроллера, где происходит приём данных от пользователя для авторизации:

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

public function actionAuth() {
        $this->pageTitle = 'Авторизация';
        $this->breadcrumbs = array('Авторизация');
        if (isGuest()) {
            $model = new UserLoginForm;
            if (isset($_POST['UserLoginForm'])) {
                $model->attributes = trimming($_POST['UserLoginForm']);
                if ($model->validate() && $model->login()) {
                    User::updateVisits();
                    $this->redirect(Yii::app()->user->getState('returnUrl', array('site/index')));
                }
            }
            $this->render($this->aid, array('model'=>$model));
        }
    }
В самой куке что-то устанавливается, как раз на неделю, правда, как всегда, кодируется фреймворком. Но почему-то не хочут это считываться из куки и сохранять авторизацию.
Приколы: юмор, анекдоты - Zasmeshi.Ru сайт на Yii, великие возможности фреймворка.
Аватара пользователя
Elfer
Сообщения: 132
Зарегистрирован: 2012.06.07, 16:09
Откуда: Беларусь, Лида
Контактная информация:

Re: Авторизация с помощью куки

Сообщение Elfer »

Может кто подскажет, где вообще смотреть в ядре метод проверки авторизации через куки? Покапаюсь там, может чего-то не хватает, параметра какого, установки.
Приколы: юмор, анекдоты - Zasmeshi.Ru сайт на Yii, великие возможности фреймворка.
Ответить