Yii для чайников \Yii for dummies (CPasswordHelper и аутентификация)

имеем таблицу юзер
//
CREATE TABLE `user`(
    `u_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ид',
    `u_username` varchar(45) NOT NULL COMMENT 'логин',
    `u_password` varchar(255) NOT NULL COMMENT 'пароль',
    `u_salt` varchar(255) DEFAULT NULL COMMENT 'соль',
    `role_r_id` int(11) DEFAULT NULL COMMENT 'роль',
    `u_comment` text COMMENT 'комментарий',
    `u_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT
     'дата создания',
    `u_ban_date` timestamp NULL DEFAULT NULL COMMENT 'дата блокировки',
    `u_dep` int(11) DEFAULT NULL COMMENT 'отдел',
    `u_sector` int(11) DEFAULT NULL COMMENT 'участок',
    `ban` tinyint(1) DEFAULT NULL COMMENT 'бан',
    PRIMARY KEY(`u_id`),
    UNIQUE KEY `u_id_UNIQUE`(`u_id`),
    UNIQUE KEY `u_username_UNIQUE`(`u_username`)
) ENGINE = InnoDB AUTO_INCREMENT = 18 DEFAULT CHARSET = utf8 COMMENT = 'юзеры';
//
создаем модель\круд
//models/User.php
<?php

/**
 * This is the model class for table "vgok_user".
 *
 * The followings are the available columns in table 'vgok_user':
 * @property integer $u_id
 * @property string $u_username
 * @property string $u_password
 * @property string $u_salt
 * @property integer $role_r_id
 * @property string $u_comment
 * @property string $u_created
 * @property string $u_ban_date
 * @property integer $u_dep
 * @property integer $u_sector
 * @property integer $ban
 *
 * The followings are the available model relations:
 * @property Engine[] $engines
 * @property Role $roleR
 * @property Department $uDep
 * @property Department $uSector
 */
class User extends CActiveRecord
{

    /**
     * @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('u_username, u_password, u_created', 'required'),
            array('role_r_id, u_dep, u_sector, ban', 'numerical'
                           'integerOnly' => true),
            array('u_username', 'match',  
                  'pattern' => '#^[a-zA-Z0-9_\.-]+$#'
                  'message' => 'Логин содержит запрещённые символы'),
            array('u_username', 'unique', 'caseSensitive' => false),
            array('u_username', 'length', 'max' => 45),
            array('u_password, u_salt', 'length', 'max' => 255),
            array('u_comment, u_ban_date', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('u_id, u_username, u_password, u_salt, role_r_id,
                   u_comment, u_created, u_ban_date, u_dep, u_sector, 
                     ban', '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(
            'u_id' => 'ид',
            'u_username' => 'логин',
            'u_password' => 'пароль',
            'u_salt' => 'соль',
            'role_r_id' => 'роль',
            'u_comment' => 'комментарий',
            'u_created' => 'дата создания',
            'u_ban_date' => 'дата блокировки',
            'u_dep' => 'отдел',
            'u_sector' => 'участок',
            'ban' => 'бан',
        );
    }

    //регистрация

    protected function beforeSave()
    {      
        $new_password = User::model()->findByPk($this->u_id)->u_password;

        if ($this->isNewRecord || $new_password != $_POST['User']['u_password'])
        {
            $this->u_password = $this->hashPassword($this->u_password);
        }

        return parent::beforeSave();
    }

    /**
     * Checks if the given password is correct.
     * @param string the password to be validated
     * @return boolean whether the password is valid
     */
    public function validatePassword($password)
    {
        return CPasswordHelper::verifyPassword($password, $this->u_password);
    }

    public function hashPassword($password)
    {
        return CPasswordHelper::hashPassword($password);
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('u_id', $this->u_id);
        $criteria->compare('u_username', $this->u_username, true);
        $criteria->compare('u_password', $this->u_password, true);
        $criteria->compare('u_salt', $this->u_salt, true);
        $criteria->compare('role_r_id', $this->role_r_id);
        $criteria->compare('u_comment', $this->u_comment, true);
        $criteria->compare('u_created', $this->u_created, true);
        $criteria->compare('u_ban_date', $this->u_ban_date, true);
        $criteria->compare('u_dep', $this->u_dep);
        $criteria->compare('u_sector', $this->u_sector);
        $criteria->compare('ban', $this->ban);

        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()
    {      
        $new_password = User::model()->findByPk($this->u_id)->u_password;

        if ($this->isNewRecord || !empty($_POST['User']['u_password']))
        {
            $this->u_password = $this->hashPassword($this->u_password);
        }

        return parent::beforeSave();
    }
//
нас интересуют новые записи и обновленные записи
//
    public function validatePassword($password)
    {
        return CPasswordHelper::verifyPassword($password, $this->u_password);
    }

    public function hashPassword($password)
    {
        return CPasswordHelper::hashPassword($password);
    }
//
hashPassword
//создает пароль
validatePassword
//проверяет правильность
//важное замечание - создать юзеров и пароли (в том числе admin) до редактирования useridentuty

//components/useridentuty.php
<?php

/**
 * UserIdentity represents the data needed to identity a user.
 * It contains the authentication method that checks if the provided
 * data can identity the user.
 */
class UserIdentity extends CUserIdentity
{

    /**
     * Authenticates a user.
     * The example implementation makes sure if the username and password
     * are both 'demo'.
     * In practical applications, this should be changed to authenticate
     * against some persistent user identity storage (e.g. database).
     * @return boolean whether authentication succeeds.
     */

    private $_id;

    public function authenticate()
    {
        $user = User::model()->find('LOWER(u_username)=?',  
                         array(strtolower($this->username)));
        if ($user === null)
            $this->errorCode = self::ERROR_USERNAME_INVALID;
        else if (!$user->validatePassword($this->password))
            $this->errorCode = self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id = $user->u_id;
            $this->username = $user->u_username;
            $this->errorCode = self::ERROR_NONE;
        }
        return !$this->errorCode;
    }

    public function getId()
    {
        return $this->_id;
    }
}
 // здесь в общем стандарт - следует только учесть нижний регистр

Комментарии

Популярные сообщения из этого блога

Пишем логи на C# (.NET). Легкий способ.

Средства для работы с базой данный PostgreSql