Spec-Zone.ru › Yii 2.0

Фильтры

  1. Использование фильтров
  2. Создание фильтров
  3. Основные фильтры

Фильтры — это объекты, которые выполняются до и/или после действий контроллера. Например, фильтр контроля доступа может выполняться до действий, чтобы убедиться, что к ним разрешен доступ определённым конечным пользователям; фильтр сжатия содержимого может выполняться после действий, чтобы сжать содержимое ответа перед отправкой конечным пользователям.

Фильтр может состоять из предобработки (логика фильтрации, применяемая до действий) и/или послеобработки (логика, применяемая после действий).

Использование фильтров

Фильтры по существу являются особым видом поведений. Поэтому использование фильтров такое же, как и использование поведений. Вы можете объявлять фильтры в классе контроллера, переопределяя его метод behaviors(), как показано ниже:

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');
            },
        ],
    ];
}

По умолчанию фильтры, объявленные в классе контроллера, будут применяться ко всем действиям в этом контроллере. Однако вы можете явно указать, к каким действиям должен применяться фильтр, настроив свойство only. В приведенном выше примере фильтр HttpCache применяется только к действиям index и view. Вы также можете настроить свойство except, чтобы поместить некоторые действия в список исключений для фильтрации.

Помимо контроллеров, вы также можете объявлять фильтры в модуле или приложении. В этом случае фильтры будут применяться ко всем действиям контроллеров, принадлежащим этому модулю или приложению, если вы не настроили свойства фильтров only и except, как описано выше.

Примечание: При объявлении фильтров в модулях или приложениях следует использовать маршруты вместо идентификаторов действий в свойствах only и except. Это связано с тем, что сами идентификаторы действий не могут полностью указать действия в рамках модуля или приложения.

Если для одного действия настроены несколько фильтров, они применяются в соответствии с правилами, описанными ниже:

  • Предварительная фильтрация
    • Применить фильтры, объявленные в приложении, в порядке их перечисления в behaviors().
    • Применить фильтры, объявленные в модуле, в порядке их перечисления в behaviors().
    • Применить фильтры, объявленные в контроллере, в порядке их перечисления в behaviors().
    • Если какой-либо из фильтров отменяет выполнение действия, то фильтры (как предварительной, так и последующей обработки), расположенные после него, не будут применяться.
  • Выполнение действия, если оно прошло предварительную фильтрацию.
  • Последующая фильтрация
    • Применить фильтры, объявленные в контроллере, в обратном порядке их перечисления в behaviors().
    • Применить фильтры, объявленные в модуле, в обратном порядке их перечисления в behaviors().
    • Применить фильтры, объявленные в приложении, в обратном порядке их перечисления в behaviors().

Создание фильтров

Чтобы создать новый фильтр действий, необходимо расширить класс yii\base\ActionFilter и переопределить методы beforeAction() и/или afterAction(). Первый из них выполняется до запуска действия, а второй — после. Значение возвращаемого методом beforeAction() определяет, должно ли выполняться действие или нет. Если оно false, фильтры, следующие за ним, будут пропущены, и действие не будет выполнено.

Следующий пример демонстрирует фильтр, который регистрирует время выполнения действия:

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::trace("Action '{$action->uniqueId}' spent $time second.");
        return parent::afterAction($action, $result);
    }
}

Основные фильтры

Yii предоставляет набор часто используемых фильтров, расположенных в основном в пространстве имён yii\filters. Далее мы кратко рассмотрим эти фильтры.

AccessControl

AccessControl обеспечивает простой контроль доступа на основе набора правил. В частности, перед выполнением действия AccessControl проверит перечисленные правила и найдёт первое, соответствующее текущим переменным контекста (например, IP-адрес пользователя, состояние входа пользователя и т. д.). Соответствующее правило будет определять, разрешено ли выполнение запрошенного действия или нет. Если ни одно правило не соответствует, доступ будет запрещён.

В следующем примере показано, как разрешить аутентифицированным пользователям доступ к действиям create и update, в то же время запретив всем остальным пользователям доступ к этим двум действиям.

use yii\filters\AccessControl;

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'only' => ['create', 'update'],
            'rules' => [
                // allow authenticated users
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
                // everything else is denied by default
            ],
        ],
    ];
}

Для получения более подробной информации о контроле доступа в целом обратитесь к разделу Авторизация.

Фильтры методов аутентификации

Фильтры методов аутентификации используются для аутентификации пользователя с помощью различных методов, таких как HTTP Basic Auth, OAuth 2. Все эти классы фильтров находятся в пространстве имён yii\filters\auth.

В следующем примере показано, как использовать yii\filters\auth\HttpBasicAuth для аутентификации пользователя с помощью маркера доступа на основе метода HTTP Basic Auth. Обратите внимание, что для этого ваша класс пользователя должен реализовывать метод findIdentityByAccessToken().

use yii\filters\auth\HttpBasicAuth;

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

Фильтры методов аутентификации обычно используются при реализации RESTful API. Для получения более подробной информации обратитесь к разделу RESTful Аутентификация.

ContentNegotiator

ContentNegotiator поддерживает согласование форматов ответов и языков приложений. Он будет пытаться определить формат и/или язык ответа, анализируя параметры GET и заголовок HTTP Accept.

В следующем примере ContentNegotiator настроен для поддержки форматов ответов JSON и XML, а также языков английский (США) и немецкий.

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

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

Форматы и языки ответов часто необходимо определять намного раньше на этапе жизненного цикла приложения. По этой причине ContentNegotiator разработан таким образом, чтобы его можно было использовать как компонент инициализации помимо использования в качестве фильтра. Например, вы можете настроить его в конфигурации приложения, как показано ниже:

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

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

Информация: В случае, если предпочтительный тип содержимого и язык не могут быть определены из запроса, будет использован первый формат и язык, перечисленный в formats и languages.

HttpCache

HttpCache реализует кэширование на стороне клиента, используя заголовки HTTP Last-Modified и Etag. Например,

use yii\filters\HttpCache;

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

Для получения дополнительной информации об использовании HttpCache обратитесь к разделу Кэширование HTTP.

PageCache

PageCache реализует кэширование целых страниц на стороне сервера. В следующем примере PageCache применяется к действию index для кэширования всей страницы на срок до 60 секунд или до тех пор, пока не изменится количество записей в таблице post. Он также сохраняет разные версии страницы в зависимости от выбранного языка приложения.

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

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

Для получения дополнительной информации об использовании PageCache обратитесь к разделу Кэширование страниц.

RateLimiter

RateLimiter реализует алгоритм ограничения скорости на основе алгоритма «дырявый ящик». Он используется в основном при реализации RESTful API. Для получения подробной информации об использовании этого фильтра обратитесь к разделу Ограничение скорости.

VerbFilter

VerbFilter проверяет, разрешены ли HTTP-методы запроса для запрошенных действий. Если они не разрешены, будет выброшено исключение HTTP 405. В следующем примере VerbFilter объявлен для указания типичного набора разрешенных методов запроса для действий CRUD.

use yii\filters\VerbFilter;

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

Cors

Cross-origin resource sharing CORS — это механизм, который позволяет многим ресурсам (например, шрифтам, JavaScript и т. д.) на веб-странице запрашиваться из другого домена, отличного от домена происхождения ресурса. В частности, вызовы AJAX JavaScript могут использовать механизм XMLHttpRequest. Такие "междоменные" запросы в противном случае были бы запрещены веб-браузерами в соответствии с политикой безопасности одного источника. CORS определяет способ взаимодействия браузера и сервера для определения возможности разрешения междоменного запроса.

Фильтр Cors должен быть определён до фильтров аутентификации/авторизации, чтобы гарантировать, что заголовки CORS всегда будут отправляться.

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

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

Также ознакомьтесь с разделом REST-контроллеры, если вы хотите добавить фильтр CORS к классу yii\rest\ActiveController в вашем API.

Фильтрацию CORS можно настроить с помощью свойства $cors.

  • cors['Origin']: массив, используемый для определения разрешенных источников. Может быть ['*'] (все) или ['http://www.myserver.net', 'http://www.myotherserver.com']. По умолчанию ['*'].
  • cors['Access-Control-Request-Method']: массив разрешенных методов, таких как ['GET', 'OPTIONS', 'HEAD']. По умолчанию ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'].
  • cors['Access-Control-Request-Headers']: массив разрешенных заголовков. Может быть ['*'] все заголовки или конкретные заголовки ['X-Request-With']. По умолчанию ['*'].
  • cors['Access-Control-Allow-Credentials']: определяет, может ли текущий запрос выполняться с использованием учетных данных. Может быть true, false или null (не задано). По умолчанию null.
  • cors['Access-Control-Max-Age']: определяет время жизни запроса предварительного пролёта. По умолчанию 86400.

Например, разрешить CORS для источника : http://www.myserver.net с методами GET, HEAD и OPTIONS :

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

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

Вы можете настроить заголовки CORS, переопределяя параметры по умолчанию для каждого действия. Например, добавление Access-Control-Allow-Credentials для действия login можно сделать так:

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

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

© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-structure-filters.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API