9. Filters | application structure | Yii Chinese document 2.0.x

filter

Filter is Controller action Objects executed before or after execution. For example, the access control filter can control whether a special end user has permission to execute an action before the action is executed, and the content compression filter can compress the response content after the action is executed and before it is sent to the end user.

The filter can include pre filtering (the filtering logic is before the action) or post filtering (the filtering logic is after the action), or both.

Use filter

Filters are essentially a special class of filters behavior So use filters and Usage behavior Same. You can override its [[yii\base\Controller::behaviors()|behaviors()]] method in the controller class to declare the filter, as follows:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            'only' => ['index', 'view'],
            'lastModified' => function ($action, $params) {
                $q = new \yii\db\Query();
                return $q->from('user')->max('updated_at');
            },
        ],
    ];
}

The filter of the controller class is applied to all actions of the class by default. You can configure the [[yii\base\ActionFilter::only|only]] attribute to specify which actions the controller applies to. In the above example, the HttpCache filter is only applied to the index and view actions. You can also configure the [[yii\base\ActionFilter::except|except]] property so that some actions do not execute the filter.

In addition to the controller, you can modular or Application subject Filter declared in. After declaration, the filter will be applied to all controller actions of the module or application subject, unless the [[yii\base\ActionFilter::only|only]] and [[yii\base\ActionFilter::except|except]] properties of the filter are configured as above.

Note: declare the filter in the module or application body and use it in the [[yii\base\ActionFilter::only|only]] and [[yii\base\ActionFilter::except|except]] attributes route Instead of the action ID, because only the action ID in the module or application body cannot be uniquely assigned to the specific action.

When an action has multiple filters, it is executed successively according to the following rules:

  • Pre filtration
    • The filters listed by behaviors() in the application body are executed sequentially.
    • The filters listed in behaviors() in the module are executed sequentially.
    • The filters listed in behaviors() in the controller are executed sequentially.
    • If any filter terminates, the subsequent filters (including pre filter and post filter) will not be executed.
  • Execute the action after successfully passing the pre filtering.
  • Post filtration
    • The filters listed in behaviors() in the controller are executed in reverse order.
    • Execute the filters listed by behaviors() in the module in reverse order.
    • Execute the filters listed by behaviors() in the application body in reverse order.

Create filter

Inherit the [[yii\base\ActionFilter]] class and override the [[yii\base\ActionFilter::beforeAction()|beforeAction()]] or [[yii\base\ActionFilter::afterAction()|afterAction()]] methods to create the filter of the action. The former is executed before the action is executed, and the latter is executed after the action is executed. [[yii\base\ActionFilter::beforeAction()|beforeAction()]] the return value determines whether the action should be executed. If it is false, subsequent filters and actions will not be executed.

The following example declares a filter that records the action execution time log.

namespace app\components;

use Yii;
use yii\base\ActionFilter;

class ActionTimeFilter extends ActionFilter
{
    private $_startTime;

    public function beforeAction($action)
    {
        $this->_startTime = microtime(true);
        return parent::beforeAction($action);
    }

    public function afterAction($action, $result)
    {
        $time = microtime(true) - $this->_startTime;
        Yii::debug("Action '{$action->uniqueId}' spent $time second.");
        return parent::afterAction($action, $result);
    }
}

Core filter

Yii provides a set of common filters. Under the yii\filters namespace, we will briefly introduce these filters.

[[yii\filters\AccessControl|AccessControl]]

AccessControl provides access control based on [[yii\filters\AccessControl::rules|rules]] rules. Especially before the action is executed, access control will detect all rules and find the rule of the first variable that conforms to the context (such as user IP address, login status, etc.) to decide whether to allow or reject the execution of the requested action. If there is no rule, access will be rejected.

The following example shows that authenticated users are allowed to access the create and update actions and other users are denied access to these two actions.

use yii\filters\AccessControl;

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::class,
            'only' => ['create', 'update'],
            'rules' => [
                // Allow authenticated users
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
                // Other users are prohibited by default
            ],
        ],
    ];
}

For more information on access control, see to grant authorization A section.

Authentication method filter

Authentication method filter passed HTTP Basic Auth or OAuth 2 To authenticate a user, the authentication method filter class is in the yii\filters\auth namespace.

The following example shows that [[yii\filters\auth\HttpBasicAuth]] can be used to authenticate a user, which uses a token based on the HTTP basic authentication method. Note that in order to run, the [[yii\web\User::identityClass|user identity class]] class must implement the [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] method.

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    return [
        'basicAuth' => [
            'class' => HttpBasicAuth::class,
        ],
    ];
}

Authentication method filters are usually used in implementing RESTful API s. For more details on access control, see RESTful authentication A section.

[[yii\filters\ContentNegotiator|ContentNegotiator]]

Content negotiator supports response content format processing and language processing. Determine the content format and language of the response by checking the GET parameter and the Accept HTTP header.

In the following example, configure ContentNegotiator to support JSON and XML response formats and English (US) and German.

use yii\filters\ContentNegotiator;
use yii\web\Response;

public function behaviors()
{
    return [
        [
            'class' => ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml' => Response::FORMAT_XML,
            ],
            'languages' => [
                'en-US',
                'de',
            ],
        ],
    ];
}

stay Application subject life cycle The format and language of the detection response in the process are much simpler, so the content negotiator design can be used Boot start component Called filter. As shown in the following example, it can be configured in Application principal configuration.

use yii\filters\ContentNegotiator;
use yii\web\Response;

[
    'bootstrap' => [
        [
            'class' => ContentNegotiator::class,
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml' => Response::FORMAT_XML,
            ],
            'languages' => [
                'en-US',
                'de',
            ],
        ],
    ],
];

Info: if the content format and language are not detected in the request, use the first configuration item of [[formats]] and [[languages]].

[[yii\filters\HttpCache|HttpCache]]

HttpCache uses last modified and Etag HTTP headers to implement client caching. For example:

use yii\filters\HttpCache;

public function behaviors()
{
    return [
        [
            'class' => HttpCache::class,
            'only' => ['index'],
            'lastModified' => function ($action, $params) {
                $q = new \yii\db\Query();
                return $q->from('user')->max('updated_at');
            },
        ],
    ];
}

For more details on using HttpCache, see HTTP cache A section.

[[yii\filters\PageCache|PageCache]]

PageCache realizes the caching of the whole page on the server side. As shown in the following example, PageCache is applied in the index action to cache the entire page for 60 seconds or the number of records in the post table changes. It will also save different page versions according to different application languages.

use yii\filters\PageCache;
use yii\caching\DbDependency;

public function behaviors()
{
    return [
        'pageCache' => [
            'class' => PageCache::class,
            'only' => ['index'],
            'duration' => 60,
            'dependency' => [
                'class' => DbDependency::class,
                'sql' => 'SELECT COUNT(*) FROM post',
            ],
            'variations' => [
                \Yii::$app->language,
            ]
        ],
    ];
}

For more information about using PageCache, see Page cache A section.

[[yii\filters\RateLimiter|RateLimiter]]

RateLimiter according to Leaky bucket algorithm To achieve rate limiting. It is mainly used to implement RESTful APIs. For more details about this filter, please refer to Rate Limiting A section.

[[yii\filters\VerbFilter|VerbFilter]]

VerbFilter checks whether the HTTP request method of the request action allows execution. If not, an HTTP 405 exception will be thrown. In the following example, VerbFilter specifies the request mode allowed by CRUD action.

use yii\filters\VerbFilter;

public function behaviors()
{
    return [
        'verbs' => [
            'class' => VerbFilter::class,
            'actions' => [
                'index'  => ['get'],
                'view'   => ['get'],
                'create' => ['get', 'post'],
                'update' => ['get', 'put', 'post'],
                'delete' => ['post', 'delete'],
            ],
        ],
    ];
}

[[yii\filters\Cors|Cors]]

Cross domain resource sharing CORS The mechanism allows many resources of a web page (such as fonts, JavaScript, etc.) to be accessed through other domain names. In particular, the AJAX call of JavaScript can use the XMLHttpRequest mechanism. Due to the homologous security policy, the cross domain request will be prohibited by the web browser. CORS defines which cross domain requests are allowed and prohibited when the browser interacts with the server.

[[yii\filters\Cors|Cors filter]] should be defined before the authorization / authentication filter to ensure that the CORS header is sent.

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
    return ArrayHelper::merge([
        [
            'class' => Cors::class,
        ],
    ], parent::behaviors());
}

If you want to add CORS filter to the [[yii\rest\ActiveController]] class in your API, you should also check REST Controllers Part of.

The CROS filter can be adjusted through the [[yii\filters\Cors::$cors|$cors]] attribute.

  • cors['Origin ']: defines the array of allowed sources, which can be [' * '] (any user) or [' http://www.myserver.net', 'http://www.myotherserver.com ']. The default is ['*'].
  • CORS ['Access control request method ']: allowed action array, such as ['Get', 'options',' head ']. The default is ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'].
  • CORS ['Access control request headers']: allow request header array, which can specify type headers for ['*'] all types of headers or ['x-request with ']. The default is ['*'].
  • CORS ['Access control allow credentials']: defines whether the current request uses a certificate, which can be true, false or null (not set). The default is null.
  • CORS ['Access control Max age ']: defines the effective time of the request. The default is 86400.

For example, the allowed source is http://www.myserver.net CORS with GET, HEAD and OPTIONS are as follows:

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
    return ArrayHelper::merge([
        [
            'class' => Cors::class,
            'cors' => [
                'Origin' => ['http://www.myserver.net'],
                'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
            ],
        ],
    ], parent::behaviors());
}

You can override the default parameters to adjust the CORS header for each action. For example, add the access control allow credentials parameter to the login action as follows:

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
    return ArrayHelper::merge([
        [
            'class' => Cors::class,
            'cors' => [
                'Origin' => ['http://www.myserver.net'],
                'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
            ],
            'actions' => [
                'login' => [
                    'Access-Control-Allow-Credentials' => true,
                ]
            ]
        ],
    ], parent::behaviors());
}

This article was first published in LearnKu.com On the website.

Added by darknessmdk on Fri, 28 Jan 2022 16:22:22 +0200