[Yii Framework] Use CPasswordHelper For Authentication

Note : available for Yii 1.1.14.

Yii framework telah merilis versi 1.1.14, salah satu fitur tambahan yang ada yaitu class CPasswordHelper terbaru : http://www.yiiframework.com/news/75/yii-1-1-14-is-released/.  Class ini sendiri menyediakan fungsi-fungsi yang dapat digunakan untuk proses autentikasi seperti register dan login. So what the different with md5 or sha? For more information about this class, you can see this wiki : http://www.yiiframework.com/wiki/425/use-crypt-for-password-storage/.

Baiklah, pada postingan ini i will explain how to use this class and compare it with md5 way.

CREATE REGISTER USER

Saya asumsikan kita memiliki tabel seperti berikut untuk tabel user :

 CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `name` varchar(45) NOT NULL,
  `password` varchar(100) NOT NULL,
  `salt_password` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

kita menggunakan password dan salt_password untuk memperkuat enkripsinya ketika kita lakukan dengan md5. Berikut implementasi untuk register user yang kita buat, pada model user kita membuat fungsi untuk generate salt_password dan men-genearate nilai hash password untuk password user.

    public function beforeValidate()
    {
        if($this->isNewRecord)
        {    
            $this->salt_password=$this->generateSalt();
            //before validate, we create random value for salt_password
        }
        return parent::beforeValidate();
    }

    public function beforeSave()
    {
        if($this->isNewRecord)
        {    
            $pword=$this->password;
            $this->password=$this->hashPassword($dua,$this->salt_password); // set password value
            // with value that have been genereate with md5
        }
        return parent::beforeSave();
    }

    // use for validate password when do login
    public function validatePassword($password)
    {
        return $this->hashPassword($password,$this->salt_password)===$this->password;
    }

   // use for generate hash password
    public function hashPassword($password,$salt)
    {
        return md5($salt.$password);
    }

   // use for generate random value
    public function generateSalt()
    {
        return uniqid('',true);
    }

Kemudian untuk fungsi loginnya, kita buat seperti berikut pada component/useridentity :

    private $_id;

    public function authenticate()
    {
        $username = strtolower($this->username);
        $user = FUser::model()->find('LOWER(username)=?', array($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->id;
            $this->username = $user->username;
            $this->errorCode = self::ERROR_NONE;

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

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

dan kode di atas, ketika kita melakukan register akan menghasilkan data seperti berikut :

 '1', 'sabit', 'sabit', 'a4057733cf4710736b652963a701746d', '520869a6a1d376.93126928'

Lalu bagaimana dengan implementasi menggunakan cpasswordhelper, yang perlu kita rubah pada bagian model menjadi seperti berikut :

    public function beforeSave()
    {
        if($this->isNewRecord)
        {    
            $pword=$this->password;
            $this->password = CPasswordHelper::hashPassword($pword);
        }
        return parent::beforeSave();
    }

Sementara itu untuk fungsi validatePassword, hashPassword, generateSalt tidak lagi digunkana pada fungsi ini. Kemudian untuk fungsi login kita buat menjadi seperti berikut :

     private $_id;

    public function authenticate()
    {
        $username = strtolower($this->username);
        $user = FUser::model()->find('LOWER(username)=?', array($username));
        if($user===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(!CPasswordHelper::verifyPassword($this->password, $user->password))// here we do change
            $this->errorCode = self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id = $user->id;
            $this->username = $user->username;
            $this->errorCode = self::ERROR_NONE;

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

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

dan dengan menggunakan cpasswordhelper, kita akan mendapatkan nilai seperti berikut :

 '3', 'andi', 'andi', '$2a$13$ESeZW/8I.lZLWZTomyUKteo0bHmTroH.G91lElgCtXOcrVfmKiPQ.', ''

You can see it we no need with salt_password again..

Finish… Hope it help… happy coding..

17 Responses to [Yii Framework] Use CPasswordHelper For Authentication

  1. asik says:

    jadi tabel salt password apakah masih perlu digunakan

  2. asik says:

    komen saya di hapus??? saya ulangi pertanyaan apakah tabel salt password masih di perlukan

  3. ga dihapus mas, saya belum sempet approve. Ga usah di pake lagi salt password nya.

  4. asik says:

    ini gk dipake yh
    public function beforeValidate()
    {
    if($this->isNewRecord)
    {
    $this->salt_password=$this->generateSalt();
    //before validate, we create random value for salt_password
    }
    return parent::beforeValidate();
    }

    kalo saya masukin error,
    kalo saya buang sukses

    Username admin
    Password $2a$13$2wFtheDDI5qluoo4oHdA4uZzKZmZgyDTbHCPDurV5RU

  5. asik says:

    saya agak bingung… saya udah bisa membuat passowrd tapi saya gk bisa login

  6. yang before validate itu untuk cara 1, yaitu pake salt password. Untuk cara ke 2 ga usah di pake lagi gan. cara loginnya juga pake cara ke dua gan..

  7. asik says:

    masih tetap gk bisa login
    model/user.php
    50),
    // The following rule is used by search().
    // @todo Please remove those attributes that should not be searched.
    array(‘id, username, password, email, tglGabung’, ‘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’,
    ‘username’ => ‘Username’,
    ‘password’ => ‘Password’,
    ’email’ => ‘Email’,
    ‘tglGabung’ => ‘Tgl Gabung’,
    );
    }

    /**
    * 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(‘id’,$this->id);
    $criteria->compare(‘username’,$this->username,true);
    $criteria->compare(‘password’,$this->password,true);
    $criteria->compare(’email’,$this->email,true);
    $criteria->compare(‘tglGabung’,$this->tglGabung,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);
    }

    public function beforeSave()
    {
    if($this->isNewRecord)
    {
    $pword=$this->password;
    $this->password=CPasswordHelper::hashPassword($pword);

    }
    return parent::beforeSave();
    }

    }
    dan user identyty
    username);
    $user = User::model()->find(‘LOWER(username)=?’,array($username));
    if($user===null)
    $this->errorCode=self::ERROR_USERNAME_INVALID;
    // else if(!$user->validatePassword($this->password))
    else if(!CPasswordHelper::verifyPassword($this->password,$user->password))
    $this->errorCode=self::ERROR_PASSWORD_INVALID;
    else
    {
    $this->_id=$user->id;
    $this->username=$user->username;
    $this->errorCode=self::ERROR_NONE;
    }
    return $this->errorCode==self::ERROR_NONE;

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

    kira2 apa yg salah

  8. asik says:

    sudah bisa login.. >>?? tapi ketika saya update password… maka Password $2a$13$2wFtheDDI5qluoo4oHdA4uZzKZmZgyDTbHCPDurV5RU <– seperti ini berubah menjadi huruf: password=admin

  9. asik says:

    emang seprti itu, itu nama nya enkripsi. ??? jawabanya kok gitu ??? solusinya gimana

  10. itu nama nya enkripsi, coba agan searching tentang enkripsi. Itu gunanya agar password kita ga dibobol orang karena kalo agan ngetik password “admin” dan di database nya ditulis “admin” ada orang yang lihat database agan dia kan jadi tahu password nya..

  11. asik says:

    yh saya tau itu enkripsi tapi solusinya gimana ketika saya update password maka ter enkripsi kembali

  12. kalo update dia memang akan di enkripsi. Atau yang agan harapkan seperti apa?

  13. asik says:

    gimana caranya supaya ter ienkripsi kembali jika di update …. passwordnya…

  14. asik says:

    maksih gan ..🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: