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]);
    }

氷落
7 声望1 粉丝

一个年过30,苦苦挣扎的程序员......