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

 不需要进行认证

ApiController

UserController extends ApiController

 需要进行认证

AuthApiController extends 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,tokenuser表中是否存在

$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]; // 63

}


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-tokenyii2_user表中不存在时,报错:You are requesting with an invalid credential.

 wKiom1cdYeKy_OYoAABHvv5ILiM503.png

 

 速率控制

   Headers下的信息:

 wKioL1cdYsuRSD4LAABRkWjVNj8000.png

 

   Body返回的信息:

 wKioL1cdYurh4zyWAABG7f9FVlo777.png