Yii2 Resultful Api 认证

Posted 氷落

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Yii2 Resultful Api 认证相关的知识,希望对你有一定的参考价值。

Yii2 Resultful Api 认证

​ 使用access token 作为用户登录认证信息

1. 修改认证

  • main.php

    /*** 认证类 ***/
    \'user\' => [
        \'identityClass\' => \'common\\models\\backend\\Admin\',
        \'enableAutoLogin\' => true,
        \'enableSession\' => FALSE, // 关闭session
        // \'identityCookie\' => [\'name\' => \'_identity-api\', \'httpOnly\' => true],
    ],
    // \'session\' => [
    //     \'name\' => \'advanced-api\',
    // ],

2. 获取access token

  • 认证类Admin

    namespace common\\models\\backend;
    
    use Yii;
    use yii\\web\\IdentityInterface;
    
    /**
     * This is the model class for table "admin".
     *
     * @property int    $id                   ID
     * @property string $username             用户名
     * @property string $realname             姓名
     * @property string $email                电子邮箱
     * @property int    $status               状态
     * @property string $password_hash        密码
     * @property string $auth_key             授权key
     * @property string $password_reset_token 密码重置token
     * @property string $access_token         访问token
     * @property int    $expire_at            过期时间
     * @property int    $logged_at            登入时间
     * @property int    $created_at           创建时间
     * @property int    $updated_at           最后修改时间
     */
    class Admin extends \\yii\\db\\ActiveRecord implements IdentityInterface
    {
        /**
         * {@inheritdoc}
         */
        public static function tableName()
        {
            return \'admin\';
        }
    
        /**
         * {@inheritdoc}
         */
        public function rules()
        {
            return [
                [[\'id\', \'email\', \'password_hash\', \'auth_key\'], \'required\'],
                [[\'id\', \'status\', \'expire_at\', \'logged_at\', \'created_at\', \'updated_at\'], \'integer\'],
                [[\'username\'], \'string\', \'max\' => 32],
                [[\'realname\', \'email\', \'password_hash\', \'auth_key\', \'password_reset_token\', \'access_token\'], \'string\',
                 \'max\' => 255],
            ];
        }
    
        /**
         * {@inheritdoc}
         */
        public function attributeLabels()
        {
            return [
                \'id\'                   => \'ID\',
                \'username\'             => \'用户名\',
                \'realname\'             => \'姓名\',
                \'email\'                => \'电子邮箱\',
                \'status\'               => \'状态\',
                \'password_hash\'        => \'密码\',
                \'auth_key\'             => \'授权key\',
                \'password_reset_token\' => \'密码重置token\',
                \'access_token\'         => \'访问token\',
                \'expire_at\'            => \'过期时间\',
                \'logged_at\'            => \'登入时间\',
                \'created_at\'           => \'创建时间\',
                \'updated_at\'           => \'最后修改时间\',
            ];
        }
    
    
        public static function findIdentity($id)
        {
            // TODO: Implement findIdentity() method.
        }
    
    
        public static function findIdentityByAccessToken($token, $type = NULL)
        {
            // TODO: Implement findIdentityByAccessToken() method.
        }
    
    
        public function getId()
        {
            // TODO: Implement getId() method.
        }
    
    
        public function getAuthKey()
        {
            // TODO: Implement getAuthKey() method.
        }
    
    
        public function validateAuthKey($authKey)
        {
            // TODO: Implement validateAuthKey() method.
        }
    
    
        /**
         * 使用用户名查找用户
         *
         * @param $username
         * @return \\common\\models\\backend\\Admin|null
         */
        public static function findByUsername($username)
        {
            return static::findOne([\'username\' => $username]);
        }
    
        /**
         * 验证密码
         *
         * @param string $password password to validate
         * @return bool if password provided is valid for current user
         */
        public function validatePassword($password)
        {
            return Yii::$app->security->validatePassword($password, $this->password_hash);
        }
    
        /**
         * 生成access token
         *
         * @return string
         * @throws \\yii\\base\\Exception
         */
        public function generateAccessToken()
        {
            $this->access_token = Yii::$app->security->generateRandomString();
            return $this->access_token;
        }
    }
    
  • 控制器文件

    namespace api\\modules\\backend\\controllers;
    
    use api\\models\\backend\\AdminLoginForm;
    
    class AdminController extends \\yii\\rest\\ActiveController
    {
        public $modelClass = "common\\models\\backend\\Admin";
    
        /**
         * 用户登录
         *
         * @return \\api\\models\\backend\\AdminLoginForm|array
         * @throws \\yii\\base\\Exception
         */
        public function actionLogin()
        {
            $model = new AdminLoginForm();
    
            $model->username = $_POST[\'username\'];
            $model->password = $_POST[\'password\'];
    
            if ($model->login()) {
                return [\'access_token\' => $model->login()];
            } else {
                $model->validate();
                return $model;
            }
        }
    }
    
  • 后台用到的登录表单模型类

    namespace api\\models\\backend;
    
    use common\\models\\backend\\Admin;
    use yii\\base\\Model;
    
    /**
     * 登录表单
     */
    class AdminLoginForm extends Model
    {
        public $username;
        public $password;
    
        /**
         * @var Admin
         */
        private $_user;
    
    
        /**
         * {@inheritdoc}
         */
        public function rules()
        {
            return [
                // username and password are both required
                [[\'username\', \'password\'], \'required\'],
                // password is validated by validatePassword()
                [\'password\', \'validatePassword\'],
            ];
        }
    
        /**
         * @param $attribute
         * @param $params
         */
        public function validatePassword($attribute, $params)
        {
            if (!$this->hasErrors()) {
                $user = $this->getUser();
                if (!$user || !$user->validatePassword($this->password)) {
                    $this->addError($attribute, \'Incorrect username or password.\');
                }
            }
        }
    
        /**
         * @return string|bool
         * @throws \\yii\\base\\Exception
         */
        public function login()
        {
            if ($this->validate()) {
                $accessToken = $this->_user->generateAccessToken();
                $this->_user->save();
                return $accessToken;
            }
            return FALSE;
        }
    
        /**
         * 查找用户
         *
         * @return Admin|null
         */
        protected function getUser()
        {
            if ($this->_user === NULL) {
                $this->_user = Admin::findByUsername($this->username);
            }
            return $this->_user;
        }
    }
    

3. 认证access token

  • 修改每个controller

    /**
         * 认证用户 access token
         * @return array
         */
    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(),[
            \'authenticatior\' => QueryParamAuth::className()
        ]);
    }
  • 实现Admin类里的findIdentityByAccessToken 方法

    /**
         * 通过access token 获取用户信息
         * @param mixed $token
         * @param null  $type
         * @return \\common\\models\\backend\\Admin|\\yii\\web\\IdentityInterface|null
         */
    public static function findIdentityByAccessToken($token, $type = NULL)
    {
        return static::findOne([\'access_token\'=>$token]);
    }

以上是关于Yii2 Resultful Api 认证的主要内容,如果未能解决你的问题,请参考以下文章

Yii2框架RESTful API教程 - 格式化响应,授权认证和速率限制

Resultful API的拦截(切片Aspect)

Resultful API的拦截(切片Aspect)

Resultful API的拦截(拦截器——Interceptor)

Resultful API的拦截(过滤器——Filter)

Resultful API的拦截(过滤器——Filter)