Stories

Detail Return Return

Yii2 Resultful Api 認證 - Stories Detail

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

Add a new Comments

Some HTML is okay.