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,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返回的信息:
本文出自 “编程艺术” 博客,请务必保留此出处http://itsart.blog.51cto.com/1005243/1767378
YII2的restfulAPI开发入门(3)-账户验证和速率控制
原文地址:http://itsart.blog.51cto.com/1005243/1767378