Yii 2.0 用户登陆 [ 2.0 版本 ]
在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
,验证通过,就登陆成功。
webclz 上海
注册时间:2014-05-07
最后登录:2024-10-22
在线时长:76小时17分
最后登录:2024-10-22
在线时长:76小时17分
- 粉丝26
- 金钱1600
- 威望60
- 积分2960
共 9 条评论
现在2.0的模型里面还有命名空间吗?
有的,很多地方都用到了命名空间
问问看看了
感觉这篇文章,是原封不动的从某处搬过来的。
不是原封不动的搬过来的
@webclz 试试啊
试试啊啊啊
太好啦!学习了。亲自试了试,确实可以完美运行。
为什么我登录成功后,
Yii::$app->user->isGuest
值还是true?这个问题你弄出来?
advanced版本好像是有个status字段的?
我试了也成功了,但是加密时咋办捏
我在
https://github.com/bubifengyun/book-yii2-dev-process
,准备借助 yiichina 里的教程,编辑成一本书,最后用某高校 LaTeX 论文模板美化一下,每月或者更长时间发布 PDF 教程总结,求支持。我想把你的教程录入到这本书里,并记录您的名字及原网址,可否?谢谢啦。
提示这个,
Call to undefined method app\models\User::findByUsername()
。不知道该咋办?如果有ip,time,role等字段呢?yii提供的登陆一样吗?