hehongwei44 / my-blog

我的博客
MIT License
137 stars 12 forks source link

Yii2如何实现用户登陆 #100

Open hehongwei44 opened 8 years ago

hehongwei44 commented 8 years ago

在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就可以实现数据表验证登陆了:

<?php

namespace app\models;

use \yii\db\ActiveRecord;
use \yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{

    /**
     * @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',
        ];
    }

    /**
     * 根据给到的ID查询身份。
     *
     * @param string|integer $id 被查询的ID
     * @return IdentityInterface|null 通过ID匹配到的身份对象
     */
    public static function findIdentity($id)
    {
        return static::findOne($id);    //static确保指向了User类。
    }

    /**
     * 根据 token 查询身份。
     *
     * @param string $token 被查询的 token
     * @return IdentityInterface|null 通过 token 得到的身份对象
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    /**
     * 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;
    }

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string 当前用户的(cookie)认证密钥
     */
    public function getAuthKey()
    {
        return $this->authKey;
    }

    /**
     * @param string $authKey
     * @return boolean if auth key is valid for current user
     */
    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;
    }
}

当通过数据表查询时候没有必要再继承\yii\base\Object,因为不必为类似原来类变量赋值了。这个时候需要User.php继承\yii\db\ActiveRecord,因为要查询用。

findIdentity是根据传递的id返回对应的用户信息,getId返回用户id,getAuthKeyvalidateAuthKey是作用于登陆中的--记住我。这个authKey是唯一的,当再次登陆时,从cookie中获取authKey传递给validateAuthKey,验证通过,就登陆成功。

hehongwei44 commented 8 years ago

想知道怎样user组件的用法可以参考这篇文章:http://www.yiichina.com/doc/guide/2.0/security-authentication

hehongwei44 commented 8 years ago

文章中static:function()的用法可以参考这篇文章:http://php.net/manual/zh/language.oop5.late-static-bindings.php