YII2中自定义用户认证模型,完成登陆和注册

有些时候我们需要自已定义用户类,操作自已建的用户表,来完成登陆和注册功能。

用户表结构如下,当然可以根据自已的需要添加或删除:

CREATE TABLE `tb_user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',`name` varchar(32) DEFAULT '' COMMENT '用户名',`pwd` varchar(64) DEFAULT '' COMMENT '密码',`head_img` varchar(256) DEFAULT '' COMMENT '图像',`sex` tinyint(1) DEFAULT '0' COMMENT '性别(0:男,1:女)',`age` tinyint(3) DEFAULT '0' COMMENT '年龄',`auth_key` varchar(32) DEFAULT '' COMMENT '认证密钥',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

然后我们在models下创建MyUser.php,代码如下:

<?php

namespace app\models;

use YII;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

//我们自定义自已的用户操作模型,需要实现IdentityInterface接口中的全部方法
//我们自定义的模型主要实现的是认证逻辑,而yii\web\User是负责管理用户认证状态的,两者是有区别的。
class MyUser extends ActiveRecord implements IdentityInterface
{
    //指定操作的表名
    public static function tableName()
    {
        return '{{%user}}';
    }

    //通过ID,返回用户实例
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    //通过令牌,返回用户实例,一般用于无状态的restful应用
    //如果你的应用不需要用到,直接留空就行
    public static function findIdentityByAccessToken($token,$type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    //通过用户名,返回用户实例
    public static function findByUsername($name)
    {
        return static::findOne(['name' => $name]);
    }

    //获取用户ID
    public function getId()
    {
        return $this->id;
    }

    //获取用户认证密钥
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    //生成cookie中的authkey
    public function generateAuthKey()
    {
        $this->auth_key = Yii::$app->security->generateRandomString(32);
        $this->save(false);
    }

    //验证用户认证密钥
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    //验证密码是否正确,当然我们也可以自已定义加密解密方式
    public function validatePassword($password)
    {
        return Yii::$app->security->validatePassword($password,$this->pwd);
    }
}

创建完我们自已的用户模型类后,我们需要在配置文件中修改成我们自已的,在config\web.php

'components' => [
	// ...
	'user' => [
		'identityClass' => 'app\models\MyUser','enableAutoLogin' => true,],];

然后我们创建一个登陆页面

<?php
use yii\helpers\Url;
?>
<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>表单提交</title>
</head>
<body>
<form action="<?php echo Url::toRoute('index/login'); ?>" method="post">
    姓名:<input type="text" name="name"><br>
    密码:<input type="password" name="pwd"><br>
    <input type="submit" value="登陆">
    <input name="_csrf" type="hidden" value="<?php echo \Yii::$app->request->csrfToken; ?>">
</form>
</body>
</html>

然后是处理用户登陆的,表单模型,在models下创建MyUserLogin.php

<?php

namespace app\models;

use Yii;
use yii\base\Model;

class MyUserLogin extends Model
{
    //注意这里要声明表单中提交过来的变量
    public $name;
    public $pwd;

    //设置验证
    public function rules()
    {
        return [
            [['name','pwd'],'required'],['pwd','validatePassword'],];
    }

    //验证密码
    public function validatePassword($attribute,$params)
    {
        if (!$this->hasErrors()) {
            $user = $this->getUser();

            if (!$user || !$user->validatePassword($this->pwd)) {
                $this->addError($attribute,'密码错误');
            }
        }
    }

    //登陆处理
    public function login()
    {
        if ($this->validate()) {
            $user = $this->getUser();
            //监听事件,登陆前,重新生成authkey
            YII::$app->user->on(\yii\web\User::EVENT_BEFORE_LOGIN,[$user,'generateAuthKey']);

            return Yii::$app->user->login($user,3600 * 24);
        }
        return false;
    }

    //获取用户
    public function getUser()
    {
        return MyUser::findByUsername($this->name);
    }
}

最后就是我们的控制器代码

<?php

namespace app\controllers;

use YII;
use yii\web\Controller;
use app\models\MyUserLogin;

class IndexController extends Controller
{
    public function actionIndex()
    {
        //当前用户的ID
        var_dump(YII::$app->user->id);
        //当前用户是否是游客
        var_dump(YII::$app->user->isGuest);
    }

    public function actionLogin()
    {
        if (YII::$app->request->isPost) {

            $model = new MyUserLogin();
            $model->load(YII::$app->request->post(),'');

            if ($model->login()) {
                echo '登陆成功';
            } else {
                echo '登陆失败';
            }

        } else {
            return $this->renderPartial('login');
        }
    }
}

演示如下:

相关文章

1、将Yii2.0advanced版中应用主体frontend或backend应用复制...
Yii2restfulAPI文档一、配置模块:1.Config/main.php:  2...
Yii在framework/i18n/data/%lang%.php文件中有很多翻译.这...
在Yii2中,官方的页面多语言解决方案有两个:方案1,使用Yii...
Yii2.0对数据库查询的一些简单的操作1234567891011121314151...
数据查询User::find()->all();此方法返回所有数据;User:...