How to login user from a database in Yii Framework 2
In this tutorial I’m going to explain how to implement login from database functionality in Yii Framework 2. I’ve seen a lot of people having problems with implementing login functionality, and with understanding the concept.
There are two classes and one interface you have to understand in order to implement login functionality in Yii Framework 2. First is a yii/web/User class which is a user component available in yii/web/Application object, the second one is your custom class which is an object which represents a database table called user, admin_user, backend_user, administrator or any other table in database which represents your website user. Your custom table should have at least the following columns: username and password where username is unique identifier of your user. Do not mix yii/web/User class which is a default Yii framework component with your custom class which can also be named User (in video I intentionally name my custom class BackendUser).
In my example, in MySQL database I created a backend_user table with the following columns:
Column name | Column description |
---|---|
id | User id |
firstName | First name of a user |
lastName | Last name of a user |
username | Username (unique) |
password | Password |
authKey | Auth key column required for cookie based login. Should be unique for every user |
Your custom class should implement an interface called IdentityInterface which defines several methods. In my example, BackendUser (my custom class which I generated using Gii tool) is implementing IdentityInterface interface, as displayed bellow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php class BackendUser extends ActiveRecord implements IdentityInterface { public static function findIdentity($id){ return static::findOne($id); } public static function findIdentityByAccessToken($token, $type = null){ throw new NotSupportedException();//I don't implement this method because I don't have any access token column in my database } public function getId(){ return $this->id; } public function getAuthKey(){ return $this->authKey;//Here I return a value of my authKey column } public function validateAuthKey($authKey){ return $this->authKey === $authKey; } public static function findByUsername($username){ return self::findOne(['username'=>$username]); } public function validatePassword($password){ return $this->password === $password; } } |
In video I explained why I added additional two functions called validatePassword() and findByUsername().
Now when you implemented your custom class (in my example called BackendUser), you have to update your web.php configuration file. In your components section, copy and paste the following code:
1 2 3 4 5 6 7 8 9 10 |
components[ ... 'user' => [ 'identityClass' => 'app\models\BackendUser', 'enableAutoLogin' => true,//If you don't have authKey column in your DB, set enableAutoLogin field to false 'enableSession' => true, ], ... ] |
As you can see, property identityClass which is defined in yii/web/User class is pointing to my custom class BackendUser which implements yii/web/IndentityInterface. If you don’t have authKey column in your database then set enableAutoLogin property to false and in your custom class (in my example BackendUser) getAuthKey and validateAuthKey like:
1 2 3 4 5 6 7 8 9 |
public function getAuthKey() { throw new NotSupportedException();//You should not implement this method if you don't have authKey column in your database } public function validateAuthKey($authKey) { throw new NotSupportedException();//You should not implement this method if you don't have authKey column in your database } |
If you don’t do it like that, you will get the following exception:
Unknown Property – yii\base\UnknownPropertyException
Getting unknown property: app\models\User::auth_key
This way you can implement login functionality from file, Active Directory (AD), database, web service or any other resource.
I’d love to get your comments below or you can email me at code.epicenter at gmail.com.
http://code-epicenter.com/how-to-login-user-from-a-database-in-yii-framework-2/How to login user from a database in Yii Framework 2http://code-epicenter.com/wp-content/uploads/2015/12/Yii2-How-to-login-user-from-a-database-Video-tutorial-1024x632.pnghttp://code-epicenter.com/wp-content/uploads/2015/12/Yii2-How-to-login-user-from-a-database-Video-tutorial-150x150.pngPHPProgrammingTutorialsVideo TutorialsYii 2tutorial,video tutorial,Yii framework,Yii Framework 2In this tutorial I'm going to explain how to implement login from database functionality in Yii Framework 2. I've seen a lot of people having problems with implementing login functionality, and with understanding the concept. There are two classes and one interface you have to understand in order to implement...Amir DuranAmir Duranamir.duran@gmail.comAdministratorAmir Duran is software engineer who currently lives and works in Germany. He obtained Masters degree diploma on Faculty of Electrical Engineering in Sarajevo, department Computer science. With good educational background he is specialized in designing and implementing a full-stack web based applications.Code Epicenter
Everything done like you but the result is “Incorrect username or password.”
Using everywhere uipass instead of password (DB structure).
Where can be problem? How to track in code? Thanks
No error, it seems that $user is empty. But in debug tool i see passed username even uipass 🙂
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->uipass)) {
$this->addError($attribute, ‘Incorrect username or password.’);
}
}
}
/**
* Logs in a user using the provided username and password.
* @return boolean whether the user is logged in successfully
*/
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
}
return false;
}
/**
* Finds user by [[username]]
*
* @return User|null
*/
public function getUser()
{
if ($this->_user === false) {
$this->_user = SelfcareUser::findByUsername($this->username);
}
return $this->_user;
}
You have misstake in your code
public function validatePassword($password)
{
$this->password === $password;
}
must be returned so:
public function validatePassword($password)
{
return $this->password === $password;
}
after this its working good
Dear Routh, thank you for pointing out that detail.
I’m glad that my tutorial helped!
Regards, Amir!
in Yii2 Advanced, there is no web.php file……… what to do….
In Yii Advanced template, you can find configuration file for Frontend in frontend/config/main.php and for Backend in backend/config/main.php.
Here are configuration files on GitHub:
Frontend configuration file: https://github.com/yiisoft/yii2-app-advanced/blob/master/frontend/config/main.php
Backend configuration file: https://github.com/yiisoft/yii2-app-advanced/blob/master/backend/config/main.php
Nice video. Thanks!
Your welcome 😉
I have one question. When I am trying to login second time with same username the password is inserting automatically. How to avoid this? Thx.
I don’t fully understand the question, but here is maybe what you can do.
If you are alredy logged in, and uwer opens login page, you can redirect him to your dashboard or desired page.
If your login form is prepopulated, clean your browser prefil values for that page
Cheers Amir
Thank you, this was great!
Your welcome, I’m glad that my video helped you!
Thank you, very helpfull.
Hi,Amir can u make video on yii2 app debugging in which we can debug app using breakpoints watch etc,much needed plz.aur give me any link reagarding this,thanx in advance
Good video !!! Thanks.
really its a good tutorial,go for it undoubtedly
thanks a lot
Hi therе, just becaame alert tо your Ьlogg thгough
Google, and found that it is truly informative. I am going to watch out for bгussels.
I աill be grateful if you continue thiѕ in future.
Many ppeople will be benefited fromm your ѡriting.
Ꮯheeгs!
Thank you for your comment and support!
Am getting the below error. Kindly assist. And thank you for the nice tutorial.
PHP Compile Error – yii\base\ErrorException
Cannot make static method yii\web\IdentityInterface::findIdentity() non static in class app\models\BackendUser
1. in C:\wamp\www\yii2.0.9\models\BackendUser.php at line 19
10111213141516171819202122232425262728
* @property integer $id
* @property string $firstname
* @property string $lastname
* @property string $username
* @property string $password
* @property string $email
* @property string $authkey
*/
class BackendUser extends \yii\db\ActiveRecord Implements \yii\web\IdentityInterface
{
/**
* @inheritdoc
*/
public static function tableName()
{
return ‘backend_user’;
}
/**
2. yii\base\ErrorHandler::handleFatalError()
Check your BackendUser class. You probably called findIndentity function on object, but it is a static method.
Thanks a lot it very helpfull.
I’m glad that my video helped you. Please subscribe to my channel so you get updates about new cool videos.
1.Very Nice and simplified tute.login module works perfectly.
Please make some more videos like this.
2.I’m also looking for batch input form. Like MARKS entry form for a particular SUBJECT of a class of 40 STUDENTS. I will be grateful if you provide me a tute. or link.
You made a great video. Thanks.
I just am trying to figure out the next step where I want to hash the password before saving in database.
So in my custom User class I am doing this:
$this->password = \Yii::$app->security->generatePasswordHash($password);
as suggested by Yii Guide. Now I am not being able to login. So can you tell my how I should now change the validatePassword function in User class accordingly?
I suppose it simply should have been:
return \Yii::$app->getSecurity()->validatePassword($password, $this->password);
But not working actually. Please suggest.
On the following link you can find good explanation about hashing a passwords:
http://www.yiiframework.com/doc-2.0/guide-security-passwords.html
Here is an idea. When a user registers on your website, then you have to hash his password and save it in DB. You can do that writing the following line:
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
You should save value of the $hash in your user/admin table.
When user logs in, then you have to check whether login password is equal with the $hash value from DB.
So obviously you have to change your validate password function a bit, and put this in function body:
public function validatePassword($password){
if (Yii::$app->getSecurity()->validatePassword($password, $this->password)) {
// all good, logging user in
} else {
// wrong password
}
}
Regards, Amir
Thank you so much for the tutorial. It helps me a lot!
I’m glad that I’ve helped 🙂
Very nice video, thanks a lot. For hashed password use “return Yii::$app->getSecurity()>validatePassword($password, $this>password);” in “vaidatePassword” method in your “BackendUser” class. “$this->password” is an already hashed user password from the database. “$password” is a non-hashed string passed as a method’s argument(user input).
dear armir,
that was a very helpful and good explanation which really is missing in the official docs.
thanks for your time and effort to share this!
best wishes!
Hi Rilke, thank you for your comment, I’m really glad that my tutorial helped you
Hello Amir
this is a really nice documentation.
My problem with this documentation is that I dont get the $this->password value in the validate password function of the model.
return $this->password === $password
ends up with 0. When I debug the session, than I can see, that there is no $this->password variable.
There is an object. I have to get and validate the password with $this->getAttribute(‘password’).
Why is it not working with my code according to your reference?
Thx, Perino
Hi,
great video tutorial.
Thank’s a lot
Hello,
1. I have Employee table whose structure is as follows:
EmpId
FirstName
LastName
Username
Password
2. Now in application coomponent I have included my custom class as follows:
‘user’ => [
‘identityClass’ => ‘app\models\Employee’,
‘enableSession’ => true,
],
3. I have implemented foll methods in Employee model as follows:
public static function findIdentity($id)
{
return static::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException();
}
public function getId()
{
return $this->EmpId;
}
public function getAuthKey()
{
throw new NotSupportedException();
}
public function validateAuthKey($authKey)
{
throw new NotSupportedException();
}
public static function findByUsername($username)
{
return self::findOne([‘Username’=>$username]);
}
public function validatePassword($password)
{
return $this->Password === $password;
}
4. And in LoginForm model, I have following. Insted of User, I have included custom class
Employee.
public function getUser()
{
if ($this->_user === false) {
$this->_user = Employee::findByUsername($this->username);
}
return $this->_user;
}
Now when I try to login and provide username and password, it gives the foll error:
Unknown Property – yii\base\UnknownPropertyException
Getting unknown property: app\models\Employee::username
Thank you so much,it helps me alot.
Hello Amir khan. many thanks for your useful! But please more tutorials about Yii!! i am very hungry about it.specially sessions and databases subjects.