在Yii2的basic版本中默認是從一個數組驗證用戶名和密碼,如何改為從數據表中查詢驗證呢?且數據庫的密碼要為哈希加密密碼驗證?
下面我們就一步一步解析Yii2的登錄過程。
一. 創建user表模型表結構如下:
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pid` int(11) NOT NULL DEFAULT '0' COMMENT '父id', `username` char(70) NOT NULL COMMENT '用戶名', `passWord` char(70) NOT NULL COMMENT '密碼', `type` tinyint(4) NOT NULL DEFAULT '4' COMMENT '類型(1:總店,2:門店,3:管理員)', `created_time` int(11) NOT NULL COMMENT '注冊時間', `updated_time` int(11) NOT NULL COMMENT '修改時間', `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '封禁狀態,0禁止1正常', `login_ip` char(20) NOT NULL COMMENT '登錄ip', `login_time` int(11) NOT NULL COMMENT '上一次登錄時間', `login_count` int(10) NOT NULL DEFAULT '0' COMMENT '登陸次數', `update_password` int(10) NOT NULL DEFAULT '0' COMMENT '修改密碼次數', PRIMARY KEY (`id`), KEY `pid` (`pid`), KEY `username` (`username`), KEY `type` (`type`), KEY `status` (`status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='登錄管理表';
使用Gii創建user模型
將Yii2 basic之前user模型代碼導入現在user中(先備份之前basic中的user模型)
1 namespace app/models; 2 3 use Yii; 4 5 /** 6 * This is the model class for table "user". 7 * 8 * @property integer $id 9 * @property integer $pid 10 * @property string $username 11 * @property string $password 12 * @property integer $type 13 * @property integer $created_time 14 * @property integer $updated_time 15 * @property integer $status 16 * @property string $login_ip 17 * @property integer $login_time 18 * @property integer $login_count 19 * @property integer $update_password 20 */ 21 class User extends /yii/db/ActiveRecord implements /yii/web/IdentityInterface 22 { public $authKey; 23 /*public $id; 24 public $username; 25 public $password; 26 public $authKey; 27 public $accessToken; 28 29 private static $users = [ 30 '100' => [ 31 'id' => '100', 32 'username' => 'admin', 33 'password' => 'admin', 34 'authKey' => 'test100key', 35 'accessToken' => '100-token', 36 ], 37 '101' => [ 38 'id' => '101', 39 'username' => 'demo', 40 'password' => 'demo', 41 'authKey' => 'test101key', 42 'accessToken' => '101-token', 43 ], 44 ]; 45 */ 46 47 /** 48 * @inheritdoc 49 */ 50 public static function tableName() 51 { 52 return 'user'; 53 } 54 55 /** 56 * @inheritdoc 57 */ 58 public function rules() 59 { 60 return [ 61 [['pid', 'type', 'created_time', 'updated_time', 'status', 'login_time', 'login_count', 'update_password'], 'integer'], 62 [['username', 'password', 'created_time', 'updated_time', 'login_ip', 'login_time'], 'required'], 63 [['username', 'password'], 'string', 'max' => 70], 64 [['login_ip'], 'string', 'max' => 20] 65 ]; 66 } 67 68 /** 69 * @inheritdoc 70 */ 71 public function attributeLabels() 72 { 73 return [ 74 'id' => 'ID', 75 'pid' => 'Pid', 76 'username' => 'Username', 77 'password' => 'Password', 78 'type' => 'Type', 79 'created_time' => 'Created Time', 80 'updated_time' => 'Updated Time', 81 'status' => 'Status', 82 'login_ip' => 'Login Ip', 83 'login_time' => 'Login Time', 84 'login_count' => 'Login Count', 85 'update_password' => 'Update Password', 86 ]; 87 } 88 89 /** 90 * @inheritdoc 91 */ 92 public static function findIdentity($id) 93 { 94 return static::findOne($id); 95 //return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; 96 } 97 98 /** 99 * @inheritdoc100 */101 public static function findIdentityByAccessToken($token, $type = null)102 {103 return static::findOne(['access_token' => $token]);104 /*foreach (self::$users as $user) {105 if ($user['accessToken'] === $token) {106 return new static($user);107 }108 }109 110 return null;*/111 }112 113 /**114 * Finds user by username115 *116 * @param string $username117 * @return static|null118 */119 public static function findByUsername($username)120 {121 $user = User::find()122 ->where(['username' => $username])123 ->asArray()124 ->one();125 126 if($user){127 return new static($user);128 }129 130 return null;131 /*foreach (self::$users as $user) {132 if (strcasecmp($user['username'], $username) === 0) {133 return new static($user);134 }135 }136 137 return null;*/138 }139 140 /**141 * @inheritdoc142 */143 public function getId()144 {145 return $this->id;146 }147 148 /**149 * @inheritdoc150 */151 public function getAuthKey()152 {153 return $this->authKey;154 }155 156 /**157 * @inheritdoc158 */159 public function validateAuthKey($authKey)160 {161 return $this->authKey === $authKey;162 }163 164 /**165 * Validates password166 *167 * @param string $password password to validate168 * @return boolean if password provided is valid for current user169 */170 public function validatePassword($password)171 {172 return $this->password === $password;173 }174 }
之前的basic中User模型是繼承了/yii/base/Object,為什么要繼承這個類,那是因為
1 #在/yii/base/Object中,有構造方法 2 public function __construct($config = []) 3 { 4 if (!empty($config)) { 5 Yii::configure($this, $config); 6 } 7 $this->init(); 8 } 9 #繼續追蹤Yii::configure($this, $config)代碼如下 10 public static function configure($object, $properties)11 {12 foreach ($properties as $name => $value) {13 $object->$name = $value;14 }15 16 return $object;17 }18 #正是因為有這兩個方法,所以在User.php中19 public static function findByUsername($username)20 {21 foreach (self::$users as $user) {22 if (strcasecmp($user['username'], $username) === 0) {23 return new static($user);24 }25 }26 27 return null;28 }29 #將$user傳遞過來,通過static,返回一個User的實例。
當通過數據表查詢時候沒有必要再繼承/yii/base/Object,因為不必為類似原來類變量賦值了。這個時候需要User模型繼承/yii/db/ActiveRecord,因為要查詢用。
findIdentity是根據傳遞的id返回對應的用戶信息,getId返回用戶id,getAuthKey和validateAuthKey是作用于登陸中的--記住我。這個authKey是唯一的,當再次登陸時,從cookie中獲取authKey傳遞給validateAuthKey,驗證通過,就登陸成功。
二. 模擬用戶數據登錄插入一條用戶模擬數據
INSERT INTO `user` (`username`, `password`) VALUES ('admin', '123')
控制器Controller
1 /** 2 * 登錄 3 */ 4 public function actionLogin() { 5 if (!/Yii::$app->user->isGuest) { 6 return $this->goHome(); 7 } 8 9 $model = new LoginForm(); 10 if ($model->load(Yii::$app->request->post()) && $model->login()) {11 12 13 $this->redirect(array('charisma/index'));14 } else {15 return $this->render('login', [16 'model' => $model,17 ]);18 }19 }
veiws中的login.php
1 <div class="well col-md-5 center login-box"> 2 <div class="alert alert-info"> 3 請填寫您的用戶名和密碼 4 </div> 5 6 <?php $form = ActiveForm::begin([ 7 'id' => 'login-form', 8
新聞熱點
疑難解答