yii2框架-restful的请求参数token验证

yii2有三种的认证方式:
1、请求参数方式: access token
也即是当作API URL请求参数发送,例如 https://example.com/users?access-token=xxxxxxxx
2、HTTP 基本认证: 发送用户名username和password, 应用在access token可安全存在API使用端的场景.例如,API使用端是运行在一台服务器上的程序
3、OAuth 2: 使用者从认证服务器上获取基于 OAuth2协议的access token,然后通过 HTTP Bearer Tokens 发送到API 服务器。

下面直说前面两种.
第一种方式:
(1)因为RESTful APIs应为无状态的, 当yii\web\User::enableSession为false, 请求中的用户认证状态就不能通过session来保持。

在控制器中重写初始化函数,设置enableSession = false

[php]  view plain  copy
 print ?
  1. public function init()  
  2. {  
  3.     parent::init();  
  4.     Yii::$app->user->enableSession = false;  

(2)重写behaviors函数,配置authenticator,引入使用的认证方式。

[php]  view plain  copy
 print ?
  1. yii\filters\auth\QueryParamAuth;  
  2. public function behaviors()  
  3. {  
  4.     $behaviors = parent::behaviors();  
  5.     $behaviors['authenticator'] = [  
  6.         'class' => QueryParamAuth::className(),  
  7.     ];  
  8.     return $behaviors;  
  9. }  
behaviors()这个函数的是定义这个控制器类的行为,也就是每一次访问这个控制器的方法,都会执行这个behaviors中定义的各种行为,认证也是这个流程,我们访问一个api接口时,就会执行yii\filters\auth\QueryParamAuth的这个文件的authenticate()这个方法



(3)我们需要在配置文件中
'user' => [
    'identityClass' => 'api\models\User',
],


指定认证的model类,现在是在api\models\User这个类中,那么我们需要在api\models\User这个类中实现yii\web\IdentityInterface这个类中的所有定义的接口方法

[php]  view plain  copy
 print ?
  1. <?php  
  2. namespace api\models;  
  3. use Yii;  
  4. use yii\base\NotSupportedException;  
  5. use yii\behaviors\TimestampBehavior;  
  6. use yii\db\ActiveRecord;  
  7. use yii\web\IdentityInterface;  
  8.   
  9. class User extends ActiveRecord implements IdentityInterface {  
  10.      /** 
  11.      * @inheritdoc 
  12.      */  
  13.     public static function tableName()  
  14.     {  
  15.         return 'users';  
  16.     }  
  17.     /** 
  18.      * @inheritdoc 
  19.      */  
  20.     public static function findIdentity($id)  
  21.     {  
  22.         return static::findOne(['id' => $id'status' => self::STATUS_ACTIVE]);  
  23.     }  
  24.   
  25.     /** 
  26.      * @inheritdoc 
  27.      */  
  28.     public static function findIdentityByAccessToken($token$type = null)  
  29.     {  
  30.         return static::findOne(['access_token' => $token]);  
  31.     }  
  32.   
  33.     //这个就是我们进行yii\filters\auth\QueryParamAuth调用认证的函数,下面会说到。  
  34.     public function loginByAccessToken($accessToken$type) {  
  35.         //查询数据库中有没有存在这个token  
  36.         return static::findIdentityByAccessToken($token$type);  
  37.     }  
  38.   
  39.     /** 
  40.      * Finds user by username 
  41.      * 
  42.      * @param string $username 
  43.      * @return static|null 
  44.      */  
  45.     public static function findByUsername($username)  
  46.     {  
  47.         return static::findOne(['username' => $username'status' => self::STATUS_ACTIVE]);  
  48.     }  
  49.   
  50.   
  51.     /** 
  52.      * @inheritdoc 
  53.      */  
  54.     public function getId()  
  55.     {  
  56.         return $this->getPrimaryKey();  
  57.     }  
  58.   
  59.     /** 
  60.      * @inheritdoc 
  61.      */  
  62.     public function getAuthKey()  
  63.     {  
  64.         return $this->auth_key;  
  65.     }  
  66.   
  67.     /** 
  68.      * @inheritdoc 
  69.      */  
  70.     public function validateAuthKey($authKey)  
  71.     {  
  72.         return $this->getAuthKey() === $authKey;  
  73.     }  
  74. }  
loginByAccessToken()这个函数是我们需要自己定义的函数,因为这个函数在yii\filters\auth\QueryParamAuth的认证类中会调用。
而findIdentityByAccessToken($token, $type = null)这个是接口函数,我们需要实现的,所以就在loginByAccessToken()这个函数中调用他去查询数据表中有没有对应的token存在,这个就是认证过程。

这样子整个认证的过程就已经完成了。例如现在我们的数据表user有一个token=xxxxxxxx,那么我们的客户端取得这个token,
我们只需要在访问的api附带这个token
http://xxxxxxx/api/v1/users?access-token=xxxxxxxxx;
那么这个url访问就会认证通过,可以返回用户列表,如果没有附带token,那么就会返回401,认证失败,不能往下执行。

下面我们来看一下yii\filters\auth\QueryParamAuth这个认证类:

[php]  view plain  copy
 print ?
  1. <?php  
  2. /** 
  3.  * @link http://www.yiiframework.com/ 
  4.  * @copyright Copyright (c) 2008 Yii Software LLC 
  5.  * @license http://www.yiiframework.com/license/ 
  6.  */  
  7.   
  8. namespace yii\filters\auth;  
  9.   
  10. /** 
  11.  * QueryParamAuth is an action filter that supports the authentication based on the access token passed through a query parameter. 
  12.  * 
  13.  * @author Qiang Xue <qiang.xue@gmail.com> 
  14.  * @since 2.0 
  15.  */  
  16. class QueryParamAuth extends AuthMethod  
  17. {  
  18.     /** 
  19.      * @var string the parameter name for passing the access token 
  20.      */  
  21.     public $tokenParam = 'access-token';  
  22.   
  23.   
  24.     /** 
  25.      * @inheritdoc 
  26.      */  
  27.     public function authenticate($user$request$response)  
  28.     {  
  29.         $accessToken = $request->get($this->tokenParam);  
  30.         if (is_string($accessToken)) {  
  31.             $identity = $user->loginByAccessToken($accessToken, get_class($this));  
  32.             if ($identity !== null) {  
  33.                 return $identity;  
  34.             }  
  35.         }  
  36.         if ($accessToken !== null) {  
  37.             $this->handleFailure($response);  
  38.         }  
  39.   
  40.         return null;  
  41.     }  
  42. }  

$tokenParam这个属性是设置url附带的token的参数key,我们可以在behaviors()这个函数中配置修改:

[php]  view plain  copy
 print ?
  1. public function behaviors() {  
  2.         $behaviors = parent::behaviors();  
  3.         $behaviors['authenticator'] = [  
  4.             'class' => QueryParamAuth::className(),  
  5.             'tokenParam' => 'token'  //例如改为‘token’  
  6.         ];  
  7.         return $behaviors;  
  8. }  
看看认证函数:
public function authenticate($user, $request, $response) {

}
$user其实就是在配置中user组件对应的api\models\User的实例,$request, $response分别是请求组件和响应组件
再看看authenticate()函数里面的这个函数
$identity = $user->loginByAccessToken($accessToken, get_class($this));

loginByAccessToken()函数也就是在api\models\User类中定义的函数,进行token的认证的。

认证通过后就返回return $identity;

那么大家又觉得奇怪,$user, $request, $response这三个参数在这个类中并没有定义,那么他们是从哪里来的呢?
其实我们可以看到这个类是继承yii\filters\auth\AuthMethod这个类的,里面有一个beforeAction()函数

[php]  view plain  copy
 print ?
  1. public function beforeAction($action)  
  2.     {  
  3.         $response = $this->response ? : Yii::$app->getResponse();  
  4.   
  5.         try {  
  6.             $identity = $this->authenticate(  
  7.                 $this->user ? : Yii::$app->getUser(),  
  8.                 $this->request ? : Yii::$app->getRequest(),  
  9.                 $response  
  10.             );  
  11.         } catch (UnauthorizedHttpException $e) {  
  12.             if ($this->isOptional($action)) {  
  13.                 return true;  
  14.             }  
  15.   
  16.             throw $e;  
  17.         }  
  18.   
  19.         if ($identity !== null || $this->isOptional($action)) {  
  20.             return true;  
  21.         } else {  
  22.             $this->challenge($response);  
  23.             $this->handleFailure($response);  
  24.             return false;  
  25.         }  
  26.     }  

所以我们执行yii\filters\auth\AuthMethod\QueryParamAuth时,也就是执行beforeAction($action)函数,这个函数调用$this->authenticate()这个函数执行,也就是进行操作前的认证。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值