авторизация по емайлу за место логина(username)

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
andry
Сообщения: 224
Зарегистрирован: 2009.11.08, 16:52

авторизация по емайлу за место логина(username)

Сообщение andry »

решил поменять username на email чтобы при авторизации указывать не логин а емайл адрес, соответственно сделал изменения

models/User.php

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

class User extends CActiveRecord
{        
    public $user;
    public $email;
    public $password;
    public $rememberMe;
    public $verifyCode;
...

    public function rules()
    {
        return array(

            array('email', 'required', 'on'=>'login', 'message' => 'Е-майл не был введён'),
            array('password', 'required', 'on'=>'login', 'message' => 'Пароль не был введён'),
            array('password','length','max'=>20, 'on'=>'login', 'message' => 'Пароль слишком длинный, должно не более 20 символов'),
            array('password', 'authenticate', 'on'=>'login'),
                             
            array('username, password', 'length', 'max'=>128, 'min' => 3, 'on'=>'registration'),
            array('username', 'match', 'pattern' => '/^[A-Za-z0-9\s,]+$/u','message' => 'Логин содержит недопустимые символы.', 'on'=>'registration'),
            array('username, password', 'required', 'on'=>'registration'),
 
            array('email', 'required', 'message' => 'Е-майл не был введён', 'on'=>'registration'),
            array('email', 'email', 'on'=>'registration'),

        );
    }
...

    public function authenticate($attribute,$params)
    {
        if(!$this->hasErrors())  
        {
            $identity=new UserIdentity($this->email,$this->password);
            $identity->authenticate();
            switch($identity->errorCode)
            {
                case UserIdentity::ERROR_NONE:
                    $duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
                    Yii::app()->user->login($identity,$duration);
                    break;
                 case UserIdentity::ERROR_USERNAME_INVALID:
                    $this->addError('email','Email is incorrect.');
                    break;                        
                default: // UserIdentity::ERROR_PASSWORD_INVALID
                    $this->addError('password','Password is incorrect.');
                    break;
            }
        }
    }    

    public function validatePassword($password)
    {
        return $this->hashPassword($password)===$this->password;
    }

    public function hashPassword($password)
    {
        return md5($password);        
    }

    protected function generateSalt()
    {
        return uniqid('',true);
    }


components/UserIdentity.php

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

class UserIdentity extends CUserIdentity
{
  protected $_id;
  //protected $email;

    public function authenticate()
    {
        $record = User::model()->find("email=? AND password=?", array($this->email,User::hashPassword($this->password) )); 

        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(!$record->validatePassword($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {                          
            $this->_id=$record->id;
            $this->username=$record->username;
            $this->email=$record->email;

            $this->errorCode=self::ERROR_NONE;
        }
        return $this->errorCode==self::ERROR_NONE;
    }

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

}

также прописал в шаблоне

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

<input name="LoginForm[email]" type="text">
 
при проверке выдало ошибку
Не определено свойство "UserIdentity.email".

я добавил в классе UserIdentity
protected $email;

после этого стало выдавать такую ошибку:
CDbCommand не удалось исполнить SQL-запрос: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined. The SQL statement executed was: SELECT * FROM `tbl_user` `t` WHERE email=? AND password=? LIMIT 1. Bound with :0=NULL, :1='21232f297a57a5a743894a0e4a801fc3'
указывая на строчку
$record = User::model()->find("email=? AND password=?", array($this->email,User::hashPassword($this->password) ));
полагаю что свойство $this->email имеет пустое значение, тоесть из формы не попадают данные веденные пользователем?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: авторизация по емайлу за место логина(username)

Сообщение ElisDN »

Оставьте стандартный UserIdentity и просто измените запрос viewtopic.php?f=3&t=9877. Сможете входить и по логину, и по емэйлу.
Последний раз редактировалось ElisDN 2013.02.08, 13:03, всего редактировалось 3 раза.
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: авторизация по емайлу за место логина(username)

Сообщение yiijeka »

всего навсего нужно было оставлять $record = User::model()->find("email=? AND password=?", array($this->email,User::hashPassword($this->password) )); вот эту строчку без изменения как было раньше, только искать там не по username а по email,

Попробуйте сейчас поменять $this->email на $this->username в UserIdentity

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

 $record = User::model()->find("email=? AND password=?", array($this->username ,User::hashPassword($this->password) )); 
andry
Сообщения: 224
Зарегистрирован: 2009.11.08, 16:52

Re: авторизация по емайлу за место логина(username)

Сообщение andry »

спасибо, всё вернул на место, исправил только в UserIdentity

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

    public function authenticate()
    {     
        $record = User::model()->find('username = :username OR email = :email', array(':username' => $this->username, ':email' => $this->username)); 
                    
        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(!$record->validatePassword($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {                    
            $this->_id=$record->id;
            $this->username=$record->username;            
            $this->errorCode=self::ERROR_NONE;
        }
        return $this->errorCode==self::ERROR_NONE;
    } 
думаю правильно

единственное теперь не знаю как правильно составить правило для проверки логина и емайла, сейчас у меня так

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

array('username', 'match', 'pattern' => '/^[A-Za-z0-9\s,]+$/u', 'on'=>'login', 'message' => 'Логин содержит недопустимые символы.'), 


к этому ещё бы добавить символы допустимые для емайла: ".","_","@"
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: авторизация по емайлу за место логина(username)

Сообщение yiijeka »

а базовый валидатор 'email' вам не подходит?
andry
Сообщения: 224
Зарегистрирован: 2009.11.08, 16:52

Re: авторизация по емайлу за место логина(username)

Сообщение andry »

но он будет работать только для емайла, а для логина уже нет. Выше дали ссылку, там вариант авторизации для логина и емайла, решил что может такой вариант будет не плохой, тоесть авторизация не только по емайлу
andry
Сообщения: 224
Зарегистрирован: 2009.11.08, 16:52

Re: авторизация по емайлу за место логина(username)

Сообщение andry »

прописал, вот теперь так работает как для логина таки для емайла

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

array('username', 'match', 'pattern' => '/^[A-Za-z0-9_.@\s,]+$/u', 'on'=>'login', 'message' => 'Логин содержит недопустимые символы.'),
gv0zd
Сообщения: 114
Зарегистрирован: 2012.03.28, 10:00

Re: авторизация по емайлу за место логина(username)

Сообщение gv0zd »

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

array('username', 'mail', 'on'=>'login', 'message' => 'Логин содержит недопустимые символы.'), 
Ответить