Yii 2 Basic User Login from Database

Perform these steps:

  • First create a user database table with your own requirements.
  • In Gii, generate a User model. In this model, implement the IdentityInterface.
    class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
    {
        //...
    }
  • Now in LoginForm model ([app]/models/LoginForm.php), define:
    class LoginForm extends Model 
    { 
        public $username; 
        public $password; 
        public $email; 
        public $rememberMe = true;
    }

User Table:(user.sql)

CREATE TABLE `user` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(250) NOT NULL,
  `last_name` VARCHAR(250) NOT NULL,
  `phone_number` VARCHAR(30) NOT NULL,
  `username` VARCHAR(250) NOT NULL,
  `email` VARCHAR(500) NOT NULL,
  `password` VARCHAR(250) NOT NULL,
  `authKey` VARCHAR(250) NOT NULL,
  `password_reset_token` VARCHAR(250) NOT NULL,
  `user_image` VARCHAR(500) NOT NULL,
  `user_level` enum('Super Admin','Admin') NOT NULL DEFAULT 'Admin'
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`),
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;

Or:

CREATE TABLE `user` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(255) NOT NULL,
  `last_name` VARCHAR(255) NOT NULL,
  `username` VARCHAR(255) NOT NULL,
  `phone` VARCHAR(255) NOT NULL,
  `email` VARCHAR(255) NOT NULL,
  `password` VARCHAR(255) NOT NULL,
  `password_hash` VARCHAR(255) NOT NULL,
  `auth_key` VARCHAR(255) NOT NULL,
  `password_reset_token` VARCHAR(250) NOT NULL,
  `avatar` VARCHAR(255) NOT NULL,
  `role` enum('Admin','Manager','Editor','Author','PowerUser','Registered') NOT NULL DEFAULT 'Registered'
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;

User Model: (@app/models/user.php)

<?php
 
namespace app\models;
use Yii;
 
use yii\db\ActiveRecord;
 
class User extends ActiveRecord implements \yii\web\IdentityInterface
{
 
   public static function tableName() 
   { 
       return 'user'; 
   }
 
   /**
    * @inheritdoc
    */
    public function rules()
    {
        return [
            [['username','password'], 'required'],
            [['user_level'], 'string'],
            [['email'], 'email'],
            [['username','email'], 'unique'],
            [['phone_number'],'string','max' => 30],
            [['username','password','password_reset_token','first_name','last_name'], 'string', 'max' => 250],
            [['user_image','email'], 'string', 'max' => 500],
            [['userimage'], 'file'],            
        ];
    }
 
    public static function findIdentity($id) 
    {
        $user = self::find()->where(["id" => $id])->one();
        if (!count($user)) {
            return null;
        }
        return new static($user);
    }
 
    /**
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $userType = null) 
    {
        $user = self::find()->where(["accessToken" => $token])->one();
        if (!count($user)) {
            return null;
        }
        return new static($user);
    }
 
    /**
     * Finds user by username
     *
     * @param  string $username
     * @return static|null
     */
    public static function findByUsername($username) 
    {
        $user = self::find()->where(["username" => $username])->one();
        if (!count($user)) {
            return null;
        }
        return new static($user);
    }
 
    public static function findByUser($username) 
    {
        $user = self::find()->where(["username" => $username])->one();
        if (!count($user)) {
            return null;
        }
        return $user;
    }
 
    /**
     * @inheritdoc
     */
    public function getId() 
    {
        return $this->id;
    }
 
    /**
     * @inheritdoc
     */
    public function getAuthKey() 
    {
        return $this->authKey;
    }
 
    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey) 
    {
        return $this->authKey === $authKey;
    }
 
    /**
     * Validates password
     *
     * @param  string  $password password to validate
     * @return boolean if password provided is valid for current user
     */
    public function validatePassword($password) 
    {
        return $this->password ===  md5($password);
    }
 
}

User Search Model: (@app/models/UserSearch.php)

<?php
 
namespace app\models;
 
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\User;
 
/**
 * UserSearch represents the model behind the search form about `app\models\User`.
 */
class UserSearch extends User
{
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id'], 'integer'],
            [['first_name', 'last_name', 'phone_number', 'username', 'email', 'password', 
              'authKey', 'password_reset_token', 'user_image', 'user_level'
            ], 'safe'],
        ];
    }
 
    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }
 
    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params)
    {
        $query = User::find();
 
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);
 
        $this->load($params);
 
        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }
 
        $query->andFilterWhere([
            'id' => $this->id,
        ]);
 
        $query->andFilterWhere(['like', 'first_name', $this->first_name])
            ->andFilterWhere(['like', 'last_name',    $this->last_name])
            ->andFilterWhere(['like', 'phone_number', $this->phone_number])
            ->andFilterWhere(['like', 'username',     $this->username])
            ->andFilterWhere(['like', 'email',        $this->email])
            ->andFilterWhere(['like', 'password',     $this->password])
            ->andFilterWhere(['like', 'authKey',      $this->authKey])
            ->andFilterWhere(['like', 'password_reset_token', $this->password_reset_token])
            ->andFilterWhere(['like', 'user_image',   $this->user_image])
            ->andFilterWhere(['like', 'user_level',   $this->user_level]);
 
        return $dataProvider;
    }
}

User Controller: (@app/controllers/UserController.php)

<?php
 
namespace app\controllers;
 
use Yii;
use app\models\User;
use app\models\UserSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
 
/**
 * UserController implements the CRUD actions for User model.
 */
class UserController extends Controller
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['post'],
                ],
            ],
        ];
    }
 
    /**
     * Lists all User models.
     * @return mixed
     */
    public function actionIndex()
    {
        $searchModel = new UserSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
 
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }
 
    /**
     * Displays a single User model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }
 
    /**
     * Creates a new User model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new User();
 
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }
 
    /**
     * Updates an existing User model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
 
        if ($model->load(Yii::$app->request->post())) {              
            return $this->redirect(['update', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }
 
    /**
     * Deletes an existing User model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
 
        return $this->redirect(['index']);
    }
 
    /**
     * Finds the User model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return User the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = User::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}

Site Controller: (@app/controllers/SiteController.php)

    public function actionLogin()
    {
        if (!\Yii::$app->user->isGuest) {
            return $this->goHome();
        }
 
        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

Login Form: (@app/views/site/login.php'')

<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
 
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \common\models\LoginForm */
 
$this->title = 'Sign In';
 
$fieldOptions1 = [
    'options' => ['class' => 'form-group has-feedback'],
    'inputTemplate' => "{input}<span class='glyphicon glyphicon-user form-control-feedback'></span>"
];
 
$fieldOptions2 = [
    'options' => ['class' => 'form-group has-feedback'],
    'inputTemplate' => "{input}<span class='glyphicon glyphicon-lock form-control-feedback'></span>"
];
?>
 
<div class="login-box">
    <div class="login-logo">
        <a href="#"><b>L</b>ogin</a>
    </div>
    <div class="login-box-body login">
        <p class="login-box-msg">Login</p>
 
        <?php $form = ActiveForm::begin(['id' => 'login-form', 'enableClientValidation' => false]); ?>
 
        <?= $form
            ->field($model, 'username', $fieldOptions1)
            ->label(false)
            ->textInput(['placeholder' => $model->getAttributeLabel('username')]) ?>
 
        <?= $form
            ->field($model, 'password', $fieldOptions2)
            ->label(false)
            ->passwordInput(['placeholder' => $model->getAttributeLabel('password')]) ?>
 
        <div class="row">
            <div class="col-xs-8">
                <?= $form->field($model, 'rememberMe')->checkbox() ?>
            </div>
            <div class="col-xs-4">
                <?= Html::submitButton('Sign in', [
                    'class' => 'btn btn-primary btn-block btn-flat', 
                    'name' => 'login-button']
                ) ?>
            </div>
        </div>
 
        <?php ActiveForm::end(); ?>
 
    </div>
 
</div>
References