yii2 api认证与授权

周滨海
2023-12-01

一、API认证的实现:可以让用户在客户端进行登录认证

步骤1:api/config/main.php  去掉cookie,session,将common\models\user改为common\models\Adminuser,增加'enableSession' => false,去掉identityCookie及session设置

return[
	'components'=>[
		'user' => [
			'identityClass' => 'common\models\Adminuser',
			'enableAutoLogin' => true,
			'enableSession' => false,
			//'identityCookie' => ['name' => '_identity-backend', 'httpOnly' =>true]
		],
		//'session' => [
			//'name' =>'advaced-backend',
		//]
	]


]

步骤2: 获得AccessToken
A、准备好需要用到的文件
包括认证类Adminuser文件(复制common/models/user.php为common/models/Adminuser.php),在代码底部加上以下代码:

public function generateAccessToken(){
	$this->access_token = Yii::$app->security->generateRandomString();
	return $this->access_token;
}


控制器文件,命名为AdminuserController,实现了登录的末端,规定了总体的登录流程

namespace api\controllers;

use yii\rest\ActiveController;
use yii\data\ActiveDataProvider;
use api\models\ApiLoginForm;

class AdminuserController extends ActiveController{
	public $modelClass= 'common\models\Adminuser';

	public function actionLgoin(){
		$mode =new ApiLoginForm();

		$model->username = $_POST['username'];
		$model->password = $_POST['password'];

		if($model->login()){
			return['access_token'=>$model->login()];
		}else{
			$model->validate();
			return $model;
		}
	}
}


后台用到的登录表单模型类ApiLoginForm(复制common/models/(Admin)LoginForm.php到api/models/apiLoginForm.php),修改login()函数
 

<?php
namespace api\models;

use Yii;
use yii\base\Model;
use common\models|Adminuser;

/**
 * Login form
 */
class AdminLoginForm extends Model
{
    public $username;
    public $password;


    private $_user;


    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            // username and password are both required
            [['username', 'password'], 'required'],
            // password is validated by validatePassword()
            ['password', 'validatePassword'],
        ];
    }

    /**
     * Validates the password.
     * This method serves as the inline validation for password.
     *
     * @param string $attribute the attribute currently being validated
     * @param array $params the additional name-value pairs given in the rule
     */
    public function validatePassword($attribute, $params)
    {
        if (!$this->hasErrors()) {
            $user = $this->getUser();
            if (!$user || !$user->validatePassword($this->password)) {
                $this->addError($attribute, 'Incorrect username or password.');
            }
        }
    }

    /**
     * Logs in a user using the provided username and password.
     *
     * @return bool whether the user is logged in successfully
     */
    public function login()
    {
        if ($this->validate()) {
            //return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
        	$accessToken = $this->_user->generateAccessToken();
        	$this->_user->save();
        	return $accessToken
        }
        
        return false;
    }

    /**
     * Finds user by [[username]]
     *
     * @return User|null
     */
    protected function getUser()
    {
        if ($this->_user === null) {
            $this->_user = User::findByUsername($this->username);
        }

        return $this->_user;
    }
}

B、客户端测试AccessToken

添加url美化规则

['class'=>'yii\rest\UrlRule',
	'controller'=>'adminuser',
	'except'=>['delete','create','update','view'],
	'pluralize'=>false,
	'extraPatterns'=>[
		'POST login' => 'login',
	],
],

小程序客户端

bindLoginTap: function(){
	var page =this;
	wx.request({
		usrl: 'http://api.apitpl.dev/adminuser/login',
		header:{
			'Content-Type':'application/x-www-form-urlencoded'
		}
		method:'POST',
		data:{
			username:"weixi",
			password:"123456"
		},
		success:function(res){
			console.log(res.data)
		}
	})
}


二、认证状态的维持:认证成功后,客户端调用服务端的API程序时,能保持认证状态。

A、api/controllers/ArticleController.php添加QueryParamAuth过滤器

public function behaviors(){
	return ArrayHelper::merge(parent::behaviors(),[
		'authenticatior' => [
			'class' => QueryParamAuth::className()
		]
	]);
}

B、common/models/Adminuser.php修改以下代码

public static function findIdentityByAccessToken($token, $type = null){
	return static::findOne(['access_token'=>$token]);
}

C、客户端代码

bindAuthReadTap: function(){
	var page =this;
	wx.request({
		usrl: 'http://api.apitpl.dev/articles?access-token=jkfa78676899766sdf',
		header:{
			'Content-Type':'application/json'
		}
		method:'GET',
		data:{
			page:1
		},
		success:function(res){
			page.setData({motto:res.data.content})
			console.log(res.data)
		}
	})
}

D、

认证类:adminuser,user,或单独建认证类
认证方式:1)请求参数:用QueryParamAuth过滤器来实现认证  2)HTTP基本认证:HTTP规范中所制定的最基本的认证方式  3) OAuth2:是一种为用户授权提供的、安全的、开放和简易的协议。
安全问题:用https来访问服务端,给令牌增加访问过期时间,http动词避免使用get而是用POST


三、API的授权:能根据RBAC的授权数据,检查发出API请求的客户端用户是否有权执行他请求的功能

1、安装yii2-admin:插件是一个配合yii2的rbac组件进行可视化管理工具
2、实现后台入口的授权功能:用yii2-admin插件实现后台应用的RBAC授权功能,在后台建立授权数据。
3、实现API应用的授权:实现API应用的RBAC授权功能,API应用共享后台应用生成的授权数据。


四、用户注册:完成注册的接口程序,让游客能在API客户端注册成为用户。

 类似资料: