api认证
1. 数据库里面把user表复制一份出来,新表名称为adminuser,里面新加一个字段access_token
2. 修改api/config/main.php
'user' => [
'identityClass' => 'common\models\Adminuser',
'enableAutoLogin' => true,
'enableSession'=>false,
// 'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
],
/* 'session' => [
// this is the name of the session cookie used for login on the backend
'name' => 'advanced-backend',
],*/
3. 在api/controllers/下新建立AdminuserController.php类
<?php
namespace api\controllers;
use yii\rest\ActiveController;
use common\models\Article;
use yii\data\ActiveDataProvider;
use api\models\ApiLoginForm;
use api\models\SignupForm;
use common\models\Adminuser;
use yii\helpers\ArrayHelper;
use yii\filters\auth\QueryParamAuth;
use yii;
class AdminuserController extends ActiveController{
public $modelClass = 'common\models\Adminuser';
public function behaviors(){
return ArrayHelper::merge(parent::behaviors(),[
'authenticatior'=>[
'class'=>QueryParamAuth::className(),
'optional' => [
'login',//客户端第一个访问login操作的时候哪来的token,yii\filters\auth\QueryParamAuth对外提供一个属性,用于过滤不需要验证的action
'signup'
],
]
]);
}
public function actionLogin(){
$model = new ApiLoginForm();
$model->username = \Yii::$app->request->post('username');
$model->password = \Yii::$app->request->post('password');
if($model->login()){
return ['access_token'=>$model->login()];
}else{
$model->validate();//带错误信息的模型
return $model;
}
}
/*public function actionRegister(){
$model = new Adminuser();
$model->username="t";
$model->password='t';
$model->email="t";
$model->save();
return $model;
} */
public function actionRegister(){
$model = new SignupForm();
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
if($model->signup()){
return ['result'=>'注册成功'];
}else{
$model->validate();//带错误信息的模型
return $model;
}
}
}
4.在api/models/下新加入ApiLoginForm.php模型类(从common/models/LoginForm.php复制)
<?php
namespace api\models;
use Yii;
use yii\base\Model;
use common\models\Adminuser;
/**
* Login form
*/
class ApiLoginForm extends Model
{
public $username;
public $password;
public $rememberMe = true;
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.');
}
}
}
public function attributeLabels(){
return[
'username'=>'用户名',
'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()) {
$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 = Adminuser::findByUsername($this->username);
}
return $this->_user;
}
}
5.在common/models/下把User.php模型类复制一份命名为Adminuser.php,修改对应的类名及token验证的函数,新加一个生成令牌access-token的函数:
public function generateAccessToken(){
$this->access_token = Yii::$app->security->generateRandomString();
return $this->access_token;
}
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token'=>$token]);
//throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
6.postman-post访问/adminusers/login获取access_token
7.修改api/models/ArticleController.php,加入阀门:
use yii\helpers\ArrayHelper;
use yii\filters\auth\QueryParamAuth;
......
public function behaviors(){
return ArrayHelper::merge(parent::behaviors(),[
'authenticatior'=>[
'class'=>QueryParamAuth::className()
]
]);
}
没有加入这个阀门之前,get访问/articles可以获取到所有文章列表,加入这个阀门后,需要带上第6步登录后获取的access_token才可以获取文章列表,需要注意的是,yii2系统默认的get请求上用access-token作为参数,为中划线