1.几个Controller之间关系的说明

⑴不需要进行认证

ApiController

UserController extends ApiController

⑵需要进行认证

AuthApiControllerextends ApiController

AuthuserController extends AuthApiController

2.只有安全认证过的api才可执行账户验证和速率控制。

⑴AuthApiController.php

<?php

namespace app\controllers;

use yii;

use yii\filters\auth\QueryParamAuth;

use yii\filters\RateLimiter;

use app\models\User;

class AuthApiController extends ApiController{

/**

* 并添加token验证

* {@inheritDoc}

* @see \yii\rest\Controller::behaviors()

*/

public function behaviors()

{

$behaviors=parent::behaviors();

$behaviors['authenticator']['class']=QueryParamAuth::className();

$behaviors['rateLimiter']['class']=RateLimiter::className();

$behaviors['rateLimiter']['enableRateLimitHeaders'] =true;

return $behaviors;

}


/**

* checkUsernameAndToken:

* 1. check token 是否 empty

* 2. username是否empty,是否符合正则规则

* checkTokenByUser:

* user表中是否存在符合条件的记录: username, accesstoken

*/

public function checkTokenUsername(){

$token=yii::$app->request->get('accesstoken');

$username=yii::$app->request->post('username');


//检查username,token在user表中是否存在

$userInfo=User::checkTokenByUser($token, $username);

if(false==$userInfo){

return ['error', 'operationIllegal'];

}

return $userInfo;

}

}

⑵AuthuserController.php

<?php

namespace app\controllers;

use yii;

use app\models\User;

class AuthuserController extends AuthApiController {


// 用户中心

public $modelClass = 'app\models\User';


/**

* 过滤数据接收方式

* {@inheritDoc}

* @see \yii\rest\ActiveController::verbs()

*/

protected function verbs(){

return [

'getuserinfo'=>['get','post'],

];

}


/**

* 获取个人信息

*/

public function actionGetuserinfo(){

$userInfo = $this->checkTokenUsername();


if(isset ($userInfo['error']))

return [‘error’=>’nouser’];

return $userInfo;

}


}

⑶最重要的User.php

<?php

namespace app\models;

use Yii;

use app\components\Utility;

use yii\web\IdentityInterface;

use yii\filters\RateLimitInterface;

class User extends \yii\db\ActiveRecord implements IdentityInterface, RateLimitInterface

{

/**

* @inheritdoc

*/

public static function tableName()

{

return '`user`';

}

/**

* @inheritdoc

*/

public function rules()

{

return [

[['username', 'password'], 'required'],

[['status', 'addtime', 'logins', 'allowance', 'allowance_updated_at'], 'integer'],

[['username', 'password', 'email'], 'string', 'max' => 64],

[['mobile'], 'string', 'max' => 11],

[['last_login_ip'], 'string', 'max' => 15],

[['access_token'], 'string', 'max' => 32],

[['access_token'], 'unique']

];

}

/**

* @inheritdoc

*/

public function attributeLabels()

{

return [

'uid' => 'Uid',

'username' => 'Username',

'password' => 'Password',

'email' => 'Email',

'status' => 'Status',

'addtime' => 'Addtime',

'mobile' => 'Mobile',

'last_login_ip' => 'Last Login Ip',

'logins' => 'Logins',

'access_token' => 'Access Token',

'allowance' => 'Allowance',

'allowance_updated_at' => 'Allowance Updated At',

];

}

/**

* @inheritdoc

* @return UserQuery the active query used by this AR class.

*/

public static function find()

{

return new UserQuery(get_called_class());

}

/**

* 授权认证. IdentityInterface

*/

public static function findIdentityByAccessToken($token, $type = null) {

return static::findOne(['access_token' => $token]);

}


public static function findIdentity($id) {

return static::findOne(['uid' => $id]);

}


public function getId() {

return $this->uid;

}


public function getAuthKey() { }


public function validateAuthKey($authKey) { }


/**

* 限速部分. RateLimitInterface

*/

public function getRateLimit($request, $action) {

return [3,6]; // 6秒3次

}


public function loadAllowance($request, $action){

return [$this->allowance,$this->allowance_updated_at];

}


public function saveAllowance($request, $action, $allowance, $timestamp){

$this->allowance=$allowance;

$this->allowance_updated_at=$timestamp;


$this->save();

}


/**

* 检查token跟用户名(手机或者邮箱)是否对应

*/

public static function checkTokenByUser($token, $user) {

$userInfo = self::findByUsername($user);

return ((!!$userInfo) && ($userInfo->access_token == $token)) ? $userInfo : false;

}

/**

* 通过username查找一个用户

*/

public static function findByUsername($username){

if(empty($username)) return false;

$sqlstr = "select * from ".self::tableName()." where username=$username";

$userInfo = self::findBySql($sqlstr)->one();

return empty($userInfo) ? false : $userInfo;

}

}

3.测试

⑴账户验证

①当access-token在yii2_user表中不存在时,报错:You are requesting with an invalid credential.

⑵速率控制

①Headers下的信息:

②Body返回的信息: