zoukankan      html  css  js  c++  java
  • 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 appmodels;
    
    use YII;
    use yiidbActiveRecord;
    use yiiwebIdentityInterface;
    
    //我们自定义自已的用户操作模型,需要实现IdentityInterface接口中的全部方法
    //我们自定义的模型主要实现的是认证逻辑,而yiiwebUser是负责管理用户认证状态的,两者是有区别的。
    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);
        }
    }
    

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

    'components' => [
    	// ...
    	'user' => [
    		'identityClass' => 'appmodelsMyUser',
    		'enableAutoLogin' => true,
    	],
    ];

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

    <?php
    use yiihelpersUrl;
    ?>
    <!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 appmodels;
    
    use Yii;
    use yiiaseModel;
    
    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(yiiwebUser::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 appcontrollers;
    
    use YII;
    use yiiwebController;
    use appmodelsMyUserLogin;
    
    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');
            }
        }
    }
    

    演示如下:

  • 相关阅读:
    TCP 连接断连问题剖析
    libtool: link: you must specify an output file
    socket编程bind浮动ip
    epoll或者kqueue的原理是什么?
    推荐 30 款最好的免费项目管理软件
    QNX开发最完整图文教程(官方文档,非官方翻译)
    Android 4.X系列の界面设计中退出Android程序的代码
    APScheduler 定时任务系统
    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
    APSchenuler嵌入Django
  • 原文地址:https://www.cnblogs.com/jkko123/p/8665496.html
Copyright © 2011-2022 走看看