[РЕШЕНО] Yii - авторизация по email (общие вопрос)

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
paloskin
Сообщения: 7
Зарегистрирован: 2012.09.30, 01:26

[РЕШЕНО] Yii - авторизация по email (общие вопрос)

Сообщение paloskin »

Добрый день!

После кучи бесплодных попыток авторизоваться используя поле email вместо username в UserIdentity и прочтения этого топика у меня возник вопрос.

Возможно ли без каких либо костылей реализовать данную авторизацию не прибегая к замене логичного $this->email на $this->username как советовали в выше сказанном топике? Или все же есть смысл делать свою авторизацию, не прибегая к UserIdentity?
Последний раз редактировалось paloskin 2012.09.30, 12:46, всего редактировалось 1 раз.
Аватара пользователя
Loki
Сообщения: 65
Зарегистрирован: 2011.01.16, 10:47
Откуда: Омск

Re: Yii - авторизация по email (общие вопрос)

Сообщение Loki »

У меня все работает без плясок с бубном...

UserIdentity

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

<?php
class UserIdentity extends CUserIdentity
{
    private $_id;
    private $_email;

    public function __construct($email, $password)
    {
        $this->_email = strtolower($email);
        $this->password = $password;
    }

    public function getId()
    {
        return $this->_id;
    }

    public function getName()
    {
        return $this->_email;
    }

    public function authenticate()
    {
        $user = User::model()->find('email=?', array($this->_email));
        if ($user == null) {
            $this->errorCode = self::ERROR_USERNAME_INVALID;
        } elseif (!$user->validatePassword($this->password)) {
            $this->errorCode = self::ERROR_PASSWORD_INVALID;
        } else {
            $this->_id = $user->id;
            Yii::app()->user->update($user);
            $this->errorCode = self::ERROR_NONE;
        }

        return !$this->errorCode;
    }
}
 
Как то так. Думаю главная фишка в:

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

    public function getName()
    {
        return $this->_email;
    }
 
paloskin
Сообщения: 7
Зарегистрирован: 2012.09.30, 01:26

Re: Yii - авторизация по email (общие вопрос)

Сообщение paloskin »

Пробую делать по вашему совету, но все никак не выходит.

Использую модель CoreUsers.

Вот что сейчас в UserIdentity

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

<?php

<?php
class UserIdentity extends CUserIdentity
{
    private $_id;
    private $_email;

    public function __construct($email, $password)
    {
        $this->_email = strtolower($email);
        $this->password = $password;
    }

    public function getId()
    {
        return $this->_id;
    }

    public function getName()
    {
        return $this->_email;
    }

    public function authenticate()
    {
        $user = CoreUsers::model()->find('email=?', array($this->_email));
        if ($user == null) {
            $this->errorCode = self::ERROR_USERNAME_INVALID;
        } elseif ($user->password !== md5($this->password)) {
            $this->errorCode = self::ERROR_PASSWORD_INVALID;
        } else {
            $this->_id = $user->id;
            Yii::app()->user->update($user);
            $this->errorCode = self::ERROR_NONE;
        }

        return !$this->errorCode;
    }
}
Это в моделях. (CoreUsers.php)

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

<?php

/**
 * This is the model class for table "core_users".
 *
 * The followings are the available columns in table 'core_users':
 * @property integer $id
 * @property string $email
 * @property string $password
 * @property integer $status
 */
class CoreUsers extends CActiveRecord
{

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return CoreUsers the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'core_users';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('email, password', 'required'),
            array('status', 'numerical', 'integerOnly'=>true),
            array('email, password', 'length', 'max'=>45),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, email, password, status', 'safe', 'on'=>'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'email' => 'Email',
            'password' => 'Password',
            'status' => 'Status',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id);
        $criteria->compare('email',$this->email,true);
        $criteria->compare('password',$this->password,true);
        $criteria->compare('status',$this->status);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }

        /**
     * Собственное правило для проверки
     * Данный метод является связующем звеном с UserIdentity
     *
     * @param $attribute
      * @param $params
     */

    public function authenticate($attribute,$params) 
    {
        $identity=new UserIdentity($this->email,$this->$password);
        if($identity->authenticate())
            Yii::app()->user->login($identity, 0);
        else
            echo $identity->errorMessage;
    }
}
Ну а это экшн контроллера CoreUsersController

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

public function actionlogin()
    {
        $form = new CoreUsers;
        
        if (!Yii::app()->user->isGuest){

            var_dump(Yii::app()->user->getId());
            die;
        } else {

            if (!empty($_POST['CoreUsers'])) {

                $form->attributes = $_POST['CoreUsers'];
                $form->status = 1;
                if ($form->validate()) {

                    $this->redirect('/login');
                }
            } 
        }

        $this->render('login', array('form' => $form));
    }
Ах да, вот еще и вьюха.

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

<?php echo CHtml::form(); ?>
<?php echo CHtml::errorSummary($form); ?><br>

    <?php echo CHtml::activeLabel($form, 'email'); ?>
        <?php echo CHtml::activeTextField($form, 'email') ?>
        
   <?php echo CHtml::activeLabel($form, 'password'); ?>        
        <?php echo CHtml::activePasswordField($form, 'password') ?>
        
        <?php echo CHtml::submitButton('Log in!'); ?>
    
<?php echo CHtml::endForm(); ?>
И все же никак не хочет логинится.
Аватара пользователя
Loki
Сообщения: 65
Зарегистрирован: 2011.01.16, 10:47
Откуда: Омск

Re: Yii - авторизация по email (общие вопрос)

Сообщение Loki »

Хм, совсем забыл про модель.
Там(в модели юзера) есть такая штука:

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

public function login()
    {
        if ($this->_identity == null) {
            $this->_identity = new UserIdentity($this->email, $this->password);
            $this->_identity->authenticate();
        }

        switch ($this->_identity->errorCode) {
            case UserIdentity::ERROR_NONE:
                $duration = $this->rememberMe ? 3600 * 24 * 14 : 0; // 14 дней
                Yii::app()->user->login($this->_identity, $duration);
                return true;
                break;
            case UserIdentity::ERROR_USERNAME_INVALID || UserIdentity::ERROR_PASSWORD_INVALID:
                $this->addError('email', 'Неверный email или пароль.');
                break;
        }
        return false;
    }
 
Тоесть когда мне нужно залогиниться я просто устанавливаю в модели User password и email и выполняю login.
Как то так:

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

    $model = new User('login');

    if (isset($_POST['User'])) {
        $model->attributes = $_POST['User'];
        if ($model->validate() && $model->login()) {
            $this->redirect(Yii::app()->user->returnUrl);
        }
    }
 
paloskin
Сообщения: 7
Зарегистрирован: 2012.09.30, 01:26

Re: Yii - авторизация по email (общие вопрос)

Сообщение paloskin »

actionLogin

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

public function actionlogin()
    {
        $form = new CoreUsers('login');
        
        if (!Yii::app()->user->isGuest){

            var_dump(Yii::app()->user->getId());
            die;
        } else {

            if (isset($_POST['CoreUsers'])) {
                $form->attributes = $_POST['CoreUsers'];
                $form->status = 1;
                if ($form->validate() && $form->login()) {
                    $this->redirect(Yii::app()->user->returnUrl);
                }
            }
        }

        $this->render('login', array('form' => $form));
    }
Модель

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

<?php

/**
 * This is the model class for table "core_users".
 *
 * The followings are the available columns in table 'core_users':
 * @property integer $id
 * @property string $email
 * @property string $password
 * @property integer $status
 */
class CoreUsers extends CActiveRecord
{

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return CoreUsers the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'core_users';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('email, password', 'required'),
            array('status', 'numerical', 'integerOnly'=>true),
            array('email, password', 'length', 'max'=>45),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, email, password, status', 'safe', 'on'=>'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'email' => 'Email',
            'password' => 'Password',
            'status' => 'Status',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id);
        $criteria->compare('email',$this->email,true);
        $criteria->compare('password',$this->password,true);
        $criteria->compare('status',$this->status);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
        ));
    }

        /**
     * Собственное правило для проверки
     * Данный метод является связующем звеном с UserIdentity
     *
     * @param $attribute
      * @param $params
     */

    public function login()
        {
            if ($this->_identity == null) {
                $this->_identity = new UserIdentity($this->email, $this->password);
                $this->_identity->authenticate();
            }

            switch ($this->_identity->errorCode) {
                case UserIdentity::ERROR_NONE:
                    $duration = $this->rememberMe ? 3600 * 24 * 14 : 0; // 14 дней
                    Yii::app()->user->login($this->_identity, $duration);
                    return true;
                    break;
                case UserIdentity::ERROR_USERNAME_INVALID || UserIdentity::ERROR_PASSWORD_INVALID:
                    $this->addError('email', 'Неверный email или пароль.');
                    break;
            }
            return false;
        }

    
}
Все равно ничего не происходит.

authenticate как я понимаю в модели не требуется оставлять?
Последний раз редактировалось paloskin 2012.09.30, 02:38, всего редактировалось 1 раз.
Аватара пользователя
Loki
Сообщения: 65
Зарегистрирован: 2011.01.16, 10:47
Откуда: Омск

Re: Yii - авторизация по email (общие вопрос)

Сообщение Loki »

Странно.
По идее, authenticate должен быть в UserIdentity, а мой login – выполняет функцию authenticate из вашей модели.
Что пишет при поптыке авторизоваться?
PS: у вас в листинге кода модели, не объявлены поля private $_identity = null; и public $rememberMe; , это опечатка, или правда не объявлено? Если и правда нет, то первое нужно объявить, а второе убрать из login.
paloskin
Сообщения: 7
Зарегистрирован: 2012.09.30, 01:26

Re: Yii - авторизация по email (общие вопрос)

Сообщение paloskin »

Да, каюсь, забыл объявить.
Объявил и убрал, но не помогло. Тоже самое.
Не пишет ничего, просто перекидывает обратно на форму ввода емэйла и пароля.
paloskin
Сообщения: 7
Зарегистрирован: 2012.09.30, 01:26

Re: Yii - авторизация по email (общие вопрос)

Сообщение paloskin »

Вообщем сейчас при использовании никуда не редиректит, появляется пустая страница. А случаем явно в login не надо передавать email и password?
Аватара пользователя
Loki
Сообщения: 65
Зарегистрирован: 2011.01.16, 10:47
Откуда: Омск

Re: Yii - авторизация по email (общие вопрос)

Сообщение Loki »

Они берутся из $this – который указывает на текущую модель, в которую мы присвоили данные из $_POST
paloskin
Сообщения: 7
Зарегистрирован: 2012.09.30, 01:26

Re: Yii - авторизация по email (общие вопрос)

Сообщение paloskin »

Все заработало. Спасибо огромное вам.
Как всегда дело оказалось в моей невнимательности.

И еще небольшой вопрос.
У вас проскочила вот такая строчка

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

Yii::app()->user->update($user);
Она выдавала ошибку. Конкретно, что нет такого метода. Не могли бы вы пояснить, что она означает?
Аватара пользователя
Loki
Сообщения: 65
Зарегистрирован: 2011.01.16, 10:47
Откуда: Омск

Re: Yii - авторизация по email (общие вопрос)

Сообщение Loki »

Это обновление пользовательских данных в сессии.
В классе WebUser у меня есть такой метод:

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

    public function update(User $user)
    {
        $this->loadIdentityStates($user->model()->attributes);
    }
 
Ответить