在yii2的basic版本中默认是从一个数组验证用户名和密码,如何改为从数据表中查询验证呢?
首先新建立一个user表并插入实验数据,如下
CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(32) NOT NULL, `authKey` varchar(100) NOT NULL DEFAULT '', `accessToken` varchar(100) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of myuser -- ---------------------------- INSERT INTO `user` VALUES ('1', 'admin', '123', '1234', '1234'); INSERT INTO `user` VALUES ('2', 'demo', '234', '123', '123');
模型User.php如下,替换掉原来的User.php就可以实现数据表验证登陆了
namespace app\models;class User extends /*\yii\base\Object*/ \yii\db\ActiveRecord implements \yii\web\IdentityInterface{ /*public $id; public $username; public $password; public $authKey; public $accessToken; private static $users = [ '100' => [ 'id' => '100', 'username' => 'admin', 'password' => 'admin', 'authKey' => 'test100key', 'accessToken' => '100-token', ], '101' => [ 'id' => '101', 'username' => 'demo', 'password' => 'demo', 'authKey' => 'test101key', 'accessToken' => '101-token', ], ]; */ /** * @inheritdoc */ public static function tableName() { return 'user'; } /** * @inheritdoc */ public function rules() { return [ [['username', 'password'], 'required'], [['username'], 'string', 'max' => 50], [['password'], 'string', 'max' => 32], [['authKey'], 'string', 'max' => 100], [['accessToken'], 'string', 'max' => 100], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'username' => 'Username', 'password' => 'Password', 'authKey' => 'AuthKey', 'accessToken' => 'AccessToken', ]; } /** * @inheritdoc */ public static function findIdentity($id) { return static::findOne($id); //return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; } /** * @inheritdoc */ public static function findIdentityByAccessToken($token, $type = null) { return static::findOne(['access_token' => $token]); /*foreach (self::$users as $user) { if ($user['accessToken'] === $token) { return new static($user); } } return null;*/ } /** * Finds user by username * * @param string $username * @return static|null */ public static function findByUsername($username) { $user = User::find() ->where(['username' => $username]) ->asArray() ->one(); if($user){ return new static($user); } return null; /*foreach (self::$users as $user) { if (strcasecmp($user['username'], $username) === 0) { return new static($user); } } return null;*/ } /** * @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 === $password; } }
原来User.php是继承了\yii\base\Object,为什么要继承这个类,是有原因的
在\yii\base\Object中,有构造方法 public function __construct($config = []) { if (!empty($config)) { Yii::configure($this, $config); } $this->init(); } 继续追踪Yii::configure($this, $config)代码如下 public static function configure($object, $properties) { foreach ($properties as $name => $value) { $object->$name = $value; } return $object; } 正是因为有这两个方法,所以在User.php中public static function findByUsername($username) { foreach (self::$users as $user) { if (strcasecmp($user['username'], $username) === 0) { return new static($user); } } return null; } 将$user传递过来,通过static,返回一个User的实例。
当通过数据表查询时候没有必要再继承\yii\base\Object,因为不必为类似原来类变量赋值了。这个时候需要User.php继承\yii\db\ActiveRecord,因为要查询用。
findIdentity是根据传递的id返回对应的用户信息,getId返回用户id,getAuthKey和validateAuthKey是 作用于登陆中的--记住我。这个authKey是唯一的,当再次登陆时,从cookie中获取authKey传递给validateAuthKey,验证 通过,就登陆成功。