Yii Framework Forum: User Authentication - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

User Authentication How is the user info & password stored in MySQL? Rate Topic: -----

#1 User is offline   Ben Collier 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 13-January 14

Posted 13 January 2014 - 09:48 AM

Hi, I've been loosely following the tutorial here, but with a MySQL backend, and developing a different application.

I was absolutely fine until I got to the authorisation section. As I'm not using the blog database data, I don't have users saved down in tbl_user. I can't work out how to encode a user in the table to make the system work, it just refuses to authorise no matter what. I've tried encoding with SHA1 and MD5 directly in MySQL, but I suspect I need to salt the password and save a salt?

Can anyone talk my through the right fields and encoding to make the setup work?

Thanks.
0

#2 User is offline   ORey 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,688
  • Joined: 20-April 09
  • Location:Moscow, Russia

Posted 13 January 2014 - 10:02 AM

It's up to you how to store passwords in DB during user creation (or pwd change), just remember to implement the proper algorythm in authenticate().

So if you choose to store plain-text passwords, you should compare $record->password and $this->password in authenticate(), and if you choose to crypt, then you can compare $record->password and your_crypt_function($this->password).

You can use this helper for crypting.

PS. I wonder if this line of code
crypt($this->password,$record->password)

is a typo. Is it ok to use password itself for salting?..
God is real unless declared as integer
0

#3 User is offline   Ben Collier 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 13-January 14

Posted 13 January 2014 - 10:09 AM

View PostORey, on 13 January 2014 - 10:02 AM, said:

It's up to you how to store passwords in DB during user creation (or pwd change), just remember to implement the proper algorythm in authenticate().


So if we're just using

CPasswordHelper::verifyPassword($password,$this->password);


..then there are no guidelines on creating early users manually in the database prior to the creation of a registration script? If we were using verifyPassword to check an entry, what would the database entry we were matching against look like? I could create a script to create some users, but if that wasn't doing the right thing, I wouldn't know if it was that script or the checker that was failing.

I'm looking for a bit of SQL like, for example:

INSERT INTO tbl_users (username, password) values ('joebloggs', MD5('Password'))


or similar.
0

#4 User is offline   ORey 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,688
  • Joined: 20-April 09
  • Location:Moscow, Russia

Posted 13 January 2014 - 10:35 AM

View PostBen Collier, on 13 January 2014 - 10:09 AM, said:

If we were using verifyPassword to check an entry, what would the database entry we were matching against look like?


From the docs:
$hash = CPasswordHelper::hashPassword($password);
This hash can be stored in a database (e.g. CHAR(64) CHARACTER SET latin1)

God is real unless declared as integer
0

#5 User is offline   Ben Collier 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 13-January 14

Posted 13 January 2014 - 11:28 AM

View PostORey, on 13 January 2014 - 10:35 AM, said:

From the docs:
$hash = CPasswordHelper::hashPassword($password);
This hash can be stored in a database (e.g. CHAR(64) CHARACTER SET latin1)



As far as I can tell from the docs, that's an MD5 hash. Is that right?
0

#6 User is offline   ORey 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,688
  • Joined: 20-April 09
  • Location:Moscow, Russia

Posted 13 January 2014 - 11:57 AM

public static function hashPassword($password,$cost=13)
{
    self::checkBlowfish();
    $salt=self::generateSalt($cost);
    $hash=crypt($password,$salt);

    if(!is_string($hash) || (function_exists('mb_strlen') ? mb_strlen($hash, '8bit') : strlen($hash))<32)
        throw new CException(Yii::t('yii','Internal error while generating hash.'));

    return $hash;
}

God is real unless declared as integer
0

#7 User is offline   MontyEdwards 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 05-February 14

Posted 05 February 2014 - 08:10 AM

View PostBen Collier, on 13 January 2014 - 09:48 AM, said:

Hi, I've been loosely following the tutorial here, but with a MySQL backend, and developing a different application.

I was absolutely fine until I got to the authorisation section. As I'm not using the blog database data, I don't have users saved down in tbl_user. I can't work out how to encode a user in the table to make the system work, it just refuses to authorise no matter what. I've tried encoding with SHA1 and MD5 directly in MySQL, but I suspect I need to salt the password and save a salt?

Can anyone talk my through the right fields and encoding to make the setup work?

Thanks.

did you ever get it to work, I am stuck in the same spot, it won't even login with the demo/demo logins,
very disappointed as I was hoping to use this feature for my website and am now stuck on it. let me know if you figure it out.
0

#8 User is offline   i.am.vj 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 7
  • Joined: 07-January 14

Posted 05 February 2014 - 12:11 PM

CPasswordHelper::hashPassword() uses Blowfish as the crypt algorithm.

This introduces excellent security on the password but, it also introduces some complexity.

The first is that you can't directly pre-propulate a MySQL table of users by enclosing the password field with MD5. You must first write a PHP script that hashes the password using the CPasswordHelper::hashPassword() function and insert the hashed value into the database.

The second is that you also can not simply do this

if($model->password == CPasswordHelper::hashPassword($form->password)) {
}

The reason is because CPasswordHelper::hashPassword() generates a different hash for the same input every time that it is called. You must instead use something like

if(CPasswordHelper::verifyPassword($form->password, $model->password)) {
}

The third thing you need to be aware of is the $cost parameter to CPasswordHelper::hashPassword($password, $cost = 13). The default of 13 may be too high for a hosted server.

You can use something like this to find the optimal cost for your server:

// Find an optimal cost to use
$timeTarget = 0.2; 
            
$cost = 5;
            
do {
    $cost++;
    $start = microtime(true);
    CPasswordHelper::hashPassword("test", $cost);
    $end = microtime(true);
} while (($end - $start) < $timeTarget);

echo "Optimal Cost: " . $cost . "\n";


Lastly, the PHP manual for the crypt() function states that in versions of PHP 5.3.7 and later, you should no longer prefix the salt with $2a$ and instead should use $2y$ because of a security flaw. Well, CPasswordHelper's generateSalt function uses the $2a$ and so, like I did, you should extend CPasswordHelper and fix the generateSalt function by changing the prefix to $2y$ if you are using PHP 5.3.7 or later.

And here is my UserIdentity::authenticate() function. Please note that it calls methods and properties that are specific to my implementation but, I hope it helps you.

    /**
     * Authenticates a user by either username or e-mail address.
     * Searching is case insensitive!
     * Uses CPasswordHelper which uses the Blowfish Crypto Algo.
     * @return boolean whether authentication succeeded.
     */
    public function authenticate()
    {
        $this->findUser();
        
        if($this->_user === null) {
            if($this->_useemail) {
                $this->errorCode = self::ERROR_EMAIL_INVALID;
            } else {
                $this->errorCode = self::ERROR_USERNAME_INVALID;
            }
        } else {
            // We have a valid user account that we need to authenticate!
            if(!$this->_user->verifyPassword($this->password)) {
                $this->errorCode = self::ERROR_PASSWORD_INVALID;
                $this->_user->loginFailed();
            } else {
                $this->processUserStatus();
            }
        }
        return !$this->errorCode;
    } // end authenticate()

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users