I have created my Yii 2 application. In my database there is a table user having the following fields: firstName, lastName, username and password, ‘authKey’.
Using Gii tool I created a model for the user table. In order to implement login functionality, I extended this class from IdentityInterface and I implemented all methods. Here is method list:
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException();
}
public static function findIdentity($id)
{
Admin::findOne($id)
}
public function getId()
{
return this->id;
}
public function getAuthKey()
{
return $this->authKey
}
public function validateAuthKey($authKey)
{
return $this->authKey = $authKey;
}
public static function findByUsername($username)
{
return static::find(array('username'=>$username));
}
public function validatePassword($password) {
return $this->password == $password;//Just for demonstration purposes
}
I changed my config file (user component to be equal to this):
<?php
namespace app\models;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
/**
* This is the model class for table "tbl_user".
*
* @property integer $id
* @property string $username
* @property string $password
* @property string $first_name
* @property string $last_name
* @property string $email
* @property integer $active
* @property string $last_login
*/
class User extends ActiveRecord implements IdentityInterface
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'tbl_user';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['username', 'password', 'first_name', 'last_name', 'email'], 'required'],
[['active'], 'integer'],
[['last_login'], 'safe'],
[['username', 'email'], 'string', 'max' => 128],
[['password'], 'string', 'max' => 255],
[['first_name', 'last_name'], 'string', 'max' => 150],
[['username'], 'unique']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'password' => 'Password',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'email' => 'Email',
'active' => 'Active',
'last_login' => 'Last Login',
];
}
/** Finds an identity by the given ID.
*
* @param string|integer $id the ID to be looked for
* @return IdentityInterface|null the identity object that matches the given ID.
*/
public static function findIdentity($id)
{
return static::findOne($id);
}
/**
* Finds an identity by the given token.
*
* @param string $token the token to be looked for
* @return IdentityInterface|null the identity object that matches the given token.
*/
public static function findIdentityByAccessToken($token, $type = null)
{
//return static::findOne(['access_token' => $token]);
}
/**
* @return int|string current user ID
*/
public function getId()
{
return $this->id;
}
/**
* @return string current user auth key
*/
public function getAuthKey()
{
//return $this->auth_key;
}
/**
* @param string $authKey
* @return boolean if auth key is valid for current user
*/
public function validateAuthKey($authKey)
{
//return $this->getAuthKey() === $authKey;
}
}
And here is my code for LoginForm
<?php
namespace app\models;
use Yii;
use yii\base\Model;
/**
* LoginForm is the model behind the login form.
*/
class LoginForm extends Model
{
public $username;
public $password;
public $rememberMe = true;
private $_user = false;
/**
* @return array the validation rules.
*/
public function rules()
{
return [
// username and password are both required
[['username', 'password'], 'required'],
// rememberMe must be a boolean value
['rememberMe', 'boolean'],
// password is validated by validatePassword()
['password', 'validatePassword'],
];
}
/**
* Validates the password.
* This method serves as the inline validation for password.
*
* @param string $attribute the attribute currently being validated
* @param array $params the additional name-value pairs given in the rule
*/
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$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 = User::findOne(['username'=> $this->username]); //User::findByUsername($this->username);
}
return $this->_user;
}
}
And here is my code from Login method.
public function actionLogin()
{
$this->layout = "login";
if (!\Yii::$app->user->isGuest) {
//return $this->goHome();
$this->redirect(['index']);
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
//return $this->goBack();
$this->redirect(['index']);
}
return $this->render('login', [
'model' => $model,
]);
}
I tried the same LoginForm.php and User.php file with different yii2 basic application there it is working perfectly fine. I’m not able to figure it out that where is a loop whole?
Thank you softark for your reply.But i don’t think that it is a redirection issue.As I believe and did a debug it is an issue with login method available in LoginForm model.
/**
* 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;
}
BTW i changed a code in login action from SiteController as give below. but nothing worked here. And redirection is working absolutely fine here.
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
Yii::$app->user->login method is not able to hold user identity after a redirection.Even i refresh a page after redirection it loose a user identity and send back user to login page.I hope it will make some scene here.