1. 程式人生 > >YII2中自定義使用者認證模型,完成登陸和註冊

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');
        }
    }
}

演示如下:

相關推薦

YII2定義使用者認證模型完成登陸註冊

有些時候我們需要自已定義使用者類,操作自已建的使用者表,來完成登陸和註冊功能。 使用者表結構如下,當然可以根據自已的需要新增或刪除: CREATE TABLE `tb_user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '使

在c語言定義了一個函式在main呼叫時提示找不到識別符號

解決方案一: 把定義的函式放在,main函式之前。 void f() { printf("Hello"); } main() { f(); } 解決方案二: 在main函式之前宣告。 void f(); main() { f

MR定義bean作為key輸出某組排序最大值。

目錄 需求:MR中自定義bean作為key,輸出某組排序中最大值。 方案:重寫MR中groupingcomparator方法 1.需求:MR中自定義bean作為key,輸出某組排序中最大值。    場景:求出多個訂單中,金額最大的商品價格。 2.方

Android定義SeekBar背景顏色進度條顏色滑塊圖片

目錄 Android SeekBar常見問題 在使用Android Seekbar大家可能經常遇到下面這幾個問題: 如何設定Seekbar進度條的高度? 如何設定滑塊的樣式? 如何設定進度條的顏色和背景顏色? 接下來,針對這三個問題我會

yii2定義表單或者post請求 csrf驗證(防跨站偽請求)

第一種解決辦法是關閉Csrf public function init(){ $this->enableCsrfValidation = false; } 第二種解決辦法是在form表單中加入csrf隱藏域表單。表單名根據我們的cookie設定

QT定義定義的結構體但是編譯報錯說這個結構體未宣告

.h檔案中自定義類及其相關變數、結構體及函式,.cpp中實現相關操作。 <在.cpp中此定義,編譯成功> inttFeaturel(unsignedchar* bD, face::DETECT_INFO*faceInfo, unsignedchar*fea

在Ignite定義身份認證安全外掛

Ignite叢集搭建完成之後,應用就可以接入叢集進行各種操作了,但是預設的叢集,沒有安全保護機制,任何應用、支援JDBC的客戶端,

定義一個校驗器--------------------------完成用戶註冊時候對username是否符合規則以及時候已經存在於數據庫的校驗

實例 check ajax -- value ava .cn java 數據 實例: <!-- 自定義校驗表單--> $.validator.addMethod( "checkusername", //校驗規則名稱,類似於required

數據庫系列之mysql 定義函數function函數存儲過程的區別

0.11 必須 def cte fec return語句 cit 新的 too mysql 自定義函數function,函數和存儲過程的區別 https://blog.csdn.net/u010365819/article/details/80470448 1.MySQL自

淺析在QtWidget定義Model(beginInsertRows()endInsertRows()是空架子類似於一種信號用來通知底層)

cti ron 初學者 開發 http 沒有 insert ati 學習 Qt 4推出了一組新的item view類,它們使用model/view結構來管理數據與表示層的關系。這種結構帶來的功能上的分離給了開發人員更大的彈性來定制數據項的表示,它也提供一個標準的model接

javaScript定義sort的比較函數用於比較字符串長度數值大小

var cti lin family 字符串長度 tr1 個數 new fun var arr = [‘aa‘, 23, 1.2, ‘bb‘, ‘cc‘]; var len = arr.length; // for (var i = 0; i < len; i++)

jqGrid細節備註—jqGrid定義格式URL格式

cto cti 函數名 pan sortable mod 51cto show 對象 本文來自:http://cnn237111.blog.51cto.com/2359144/782137 jqGrid中自定義格式,URL格式 當官方自帶的showlink用起來不是十分

Lambda語句創建定義類型時也可指定某種特定類型方法是在new與{}之間寫上類型名稱

特定 pan sel lambda語句 lam {} where distinct select 如: var fc =...ChildFath = fc.Select(c => new Child_Father { child = c.child, father =

JavaScript定義函數以及文本框、radio、下拉框的值的獲取結合淘寶競拍案例來理解。。。

支付寶 價格 select back html alt 文本框 lec 獲取 淘寶競拍案例: HTML部分代碼: <form action="#" method="post"> <h2>歡迎進入淘寶競拍</h2> &l

定義jquery的方法將Form表單的內容轉換成json

// 自定義jquery的方法,將Form表單中的內容轉換成json $.fn.serializeJson=function(){ var serializeObj={}; var array=this

建立表、修改表、刪除表的方法 建立主鍵約束、外來鍵約束、使用者定義約束的方法 建立查詢表的方法及使用截斷表的方法理解約束在資料庫的作用

撰寫人——軟工二班——陳喜平 – 實驗內容: – 一、建立表 – 建立圖書館管理系統所涉及的表 – 建立產品銷售系統所涉及的表 – 圖書表book(bid,bname,price,qty) – 書庫表lib(lid,lname,address) – 讀者表reader

Hive面試題:請寫出你在工作定義過的udf函式簡述定義步驟

步驟: 1.extends UDF,實現evaluate() 2.add JAR /home/hadoop/hivejar/udf.jar; 3.create temporary function tolowercase as 'com.ghgj.hive.udf.ToLowerCa

獲取實現了某介面的所有類並返回該類定義的方法的方法名

準備階段:   定義介面和實現介面的類。 interface IMyInterface { void Write(); } /// <summary> /// 實現類1 /// </summary>

Springboot定義springmvc攔截器;HandlerInterceptorpreHandlepostHandleafterCompletion解析

要實現自定義HandlerInterceptor 。通過 WebMvcConfigurer 的實現類屬性注入,完成springboot自定義攔截 自定義一個攔截器; package com.baidu.

織夢繫統定義搜尋模型不存在”的解決方法

搜尋了一下關於自定義搜尋模型不存在這個問題 重新整理下:1.mysql 資料庫在5.0版本以上2. 自定義搜尋表dede_advancedsearch 這個表的結構把256 改成255 3.還有就是搜