D
D
davidnum952014-02-20 20:10:46
Yii
davidnum95, 2014-02-20 20:10:46

Yii Framework: how to set up authorization and authentication?

Friends, for 2 days now I can not figure out the authorization. Why can't I log in?
Here is the model code:

class User extends CActiveRecord
{
    const SCENARIO_REGISTER = 'register';
    const SCENARIO_LOGIN = 'login';

    private $_identity;

    public $password_repeat;

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

    /**
     * @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('username, password', 'required'),
            array('username', 'unique'),
            array('username', 'length', 'min'=>5, 'max'=>30),
            array('username', 'match', 'pattern'=>'/^[A-z][\w]+$/'),
            array('password', 'length', 'min'=>6, 'max'=>30),
            array('password', 'authenticate', 'on'=>'login'),
            array('password_repeat, email', 'required', 'on'=>'register'),
            array('password_repeat', 'length', 'min'=>6, 'max'=>30),
            array('password', 'compare', 'compareAttribute'=>'password_repeat', 'on'=>'register'),
            array('email', 'email', 'on'=>'register'),
            array('email', 'length', 'min'=>6, 'max'=>30),
            array('email', 'filter', 'filter'=>'mb_strtolower'),
            array('id, username, password, email, dtime_register, cookie', 'safe', 'on'=>'search'),

        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        return array();
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'username' => 'Username',
            'password' => 'Password',
            'password_repeat' => 'Repeat password',
            'email' => 'Email',
        );
    }

    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria=new CDbCriteria;

        $criteria->compare('id',$this->id);
        $criteria->compare('username',$this->username,true);
        $criteria->compare('password',$this->password,true);
        $criteria->compare('email',$this->email,true);
        $criteria->compare('dtime_register',$this->dtime_register,true);
        $criteria->compare('cookie',$this->cookie,true);

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

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return User the static model class
     */
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    protected function beforeSave() {
        if(parent::beforeSave()) {
            if($this->getIsNewRecord()) {
                $this->dtime_register = time();
                $this->password = md5($this->password);
            }

            return true;
        }
        return false;
    }

    public function authenticate() {
        if(!$this->hasErrors()) {
            $this->_identity = new UserIdentity($this->username, $this->password);
            if(!$this->_identity->authenticate()) {
                $this->addError('password', 'Incorrect username or password');
            }
        }
    }

    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) {
            $duration = 3600*24*30;
            Yii::app()->user->login($this->_identity, $duration);
            return true;
        }
        else {
            return false;
        }
    }

    public function logout() {
       // ...
    }

}

UserIdentity:
class UserIdentity extends CUserIdentity
{
    private $_id;

    public function authenticate()
    {
        $record = User::model()->findByAttributes(array('username'=>$this->username));
        if($record === null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(md5($this->password) !== $record->password)
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id = $record->id;
            $this->setState('username', $record->username );
            $this->errorCode=self::ERROR_NONE;
        }
        return !$this->errorCode;
    }

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

and the action itself on the controller:
public function actionLogin() {

        $user = new User(User::SCENARIO_LOGIN);

        if(isset($_POST['User'])) {
            $user->attributes = $_POST['User'];
            if($user->login()) {
                $this->redirect('/');
            }
        }

        $this->render('login', array('model'=>$user));
    }

Answer the question

In order to leave comments, you need to log in

4 answer(s)
_
_ _, 2014-02-20
@AMar4enko

He wrote and wrote, then spat. Everything is bad in this code. I don't know how to help you.

V
Vit, 2014-02-20
@fornit1917

Wrong password check. If you have a real password value in the password field in your model, then in Identity you hash it and compare it with yourself.
If there is a hash in the model, then fail again: you hash it again and compare it with yourself.

I
Ivan Karabadzhak, 2014-02-20
@Jakeroid

You have a bad question. From the category of "why the site does not work?", After all, there is no specifics. Connect xdebug or even the same var_dump find where the error is and ask for advice on how to solve it. And so you posted your code, and you want us to find where your error is? Is it because you are lazy or you don't know how to search?
What actually happens after a login attempt? What value does the login() method return?

_
_ _, 2014-02-20
@AMar4enko

People, sorry for the question on an abstract topic, but is xdebug unpopular these days?
And
how do they relate to each other?
You have a hash for the password when saving it is generated in one way, and the hash for the password entered by the user is taken as md5. They will never be the same.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question