Reputation: 23
I try to enable RateLimiter and follow documentation for Yii2 https://www.yiiframework.com/doc/guide/2.0/en/rest-rate-limiting
I test it with logged user and in info log I have:
2020-04-21 16:50:35 [172.18.0.1][5][-][info][yii\filters\RateLimiter::beforeAction] Rate limit skipped: user not logged in.
2020-04-21 16:50:35 [172.18.0.1][5][-][info][yii\web\User::login] User '5' logged in from 172.18.0.1. Session not enabled.
So RateLimiter check user before it logged in? Any suggestions?
UPDATE - behaviors()
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBearerAuth::className(),
],
];
$behaviors['verbs'] = [
'class' => \yii\filters\VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'create' => ['post'],
'update' => ['put'],
'delete' => ['delete'],
],
];
// remove authentication filter
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
// add CORS filter
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
'Origin' => ['*'],
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
'Access-Control-Request-Headers' => ['*'],
],
];
// re-add authentication filter
$behaviors['authenticator'] = $auth;
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
$behaviors['authenticator']['except'] = [
'options',
];
$behaviors['access'] = [
'class' => AccessControl::className(),
'rules' => [
....
],
];
return $behaviors;
}
Upvotes: 2
Views: 1074
Reputation: 6169
Event handlers are triggered in the order they are registered. In case of behaviors that means that the order in which you are defining the behaviors will decide the order in which they are executed.
The behaviors defined in the yii\rest\Controller
looks like this:
public function behaviors()
{
return [
'contentNegotiator' => [
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
],
'verbFilter' => [
'class' => VerbFilter::className(),
'actions' => $this->verbs(),
],
'authenticator' => [
'class' => CompositeAuth::className(),
],
'rateLimiter' => [
'class' => RateLimiter::className(),
],
];
}
That means that the authenticator behavior should be executed before the rateLimiter.
But in your code you are unsetting the authenticator definition and then adding it back after you add some other behaviors. That moves authenticator behind the rateLimiter and causes that the rateLimiter is executed first.
You need to do same thing with rateLimiter as you are doing with the authenticator.
public function behaviors()
{
$behaviors = parent::behaviors();
$rateLimiter = $behaviors['rateLimiter'];
unset($behaviors['rateLimiter']);
// ... other code ...
// re-add authentication filter
$behaviors['authenticator'] = $auth;
// re-add rate limiter
$behaviors['rateLimiter'] = $rateLimiter;
// ... the rest of code
}
Upvotes: 4