Пре- и постфильтры
Фильтры — это обработчики, которые выполняются до или после действия контроллера (Action). Они могут отменить выполнение действия или изменить его результат. Фильтры помогают сделать код более модульным и управляемым, обеспечивая дополнительный уровень контроля над выполнением действий.
Типы фильтров
-
Префильтры (prefilter) — выполняются до запуска действия. Могут отменить выполнение.
-
Постфильтры (postfilter) — выполняются после действия. Могут изменить результат.
Основные фильтры
Фильтр HTTP-методов
\Bitrix\Main\Engine\ActionFilter\HttpMethod
Проверяет HTTP-метод действия и блокирует выполнение, если метод не разрешен. Нужен, когда необходимо ограничить выполнение действия только определенными HTTP-методами, например, POST для изменения данных.
Аргументы:
$allowedMethods— список допустимых HTTP-методов. По умолчанию —GET.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\HttpMethod;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new HttpMethod([
HttpMethod::METHOD_GET,
HttpMethod::METHOD_POST,
]),
])]
public function indexAction()
{
// ...
}
}
Имеет аналог в виде атрибута:
use Bitrix\Main\Engine\ActionFilter\HttpMethod;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[\Bitrix\Main\Engine\ActionFilter\Attribute\Rule\HttpMethod(
HttpMethod::METHOD_GET,
HttpMethod::METHOD_POST,
)]
public function indexAction()
{
// ...
}
}
Фильтр аутентификации
\Bitrix\Main\Engine\ActionFilter\Authentication
Проверяет аутентификацию пользователя и блокирует действие, если проверка не пройдена (HTTP статус 401). Может перенаправить на страницу авторизации. Используется для защиты действий, требующих аутентификации, например, доступ к личным данным пользователя.
Аргументы:
$enableRedirect— включает редирект на авторизацию. По умолчанию —false.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\Authentication;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new Authentication(true),
])]
public function indexAction()
{
// ...
}
}
Имеет аналог в виде атрибута:
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[\Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Authentication(true)]
public function indexAction()
{
// ...
}
}
Фильтр CSRF-защиты
\Bitrix\Main\Engine\ActionFilter\Csrf
Проверяет наличие и корректность CSRF-токена и блокирует действие, если проверка не пройдена. Необходим для защиты от CSRF-атак, особенно в формах и AJAX-запросах.
Аргументы:
-
$enabled— включает проверку токена. По умолчанию —true. -
$tokenName— имя токена. По умолчанию —'sessid'. -
$returnNew— возвращает новый токен при неудаче. По умолчанию —true.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\Csrf;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new Csrf(
tokenName: 'sessid',
returnNew: false,
),
])]
public function indexAction()
{
// ...
}
}
Имеет аналог в виде атрибута:
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[\Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Csrf(
tokenName: 'sessid',
returnNew: false,
)]
public function indexAction()
{
// ...
}
}
Фильтр закрытия сессии
\Bitrix\Main\Engine\ActionFilter\CloseSession
Закрывает сессию перед выполнением действия. Полезен для повышения производительности, когда изменения в сессии не требуются. Будьте внимательны, так как изменения в сессии после закрытия не сохранятся.
Атрибуты:
$enabled— включает фильтр. По умолчанию —true.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\CloseSession;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new CloseSession(),
])]
public function indexAction()
{
// ...
}
}
Имеет аналог в виде атрибута:
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[\Bitrix\Main\Engine\ActionFilter\Attribute\Rule\CloseSession]
public function indexAction()
{
// ...
}
}
Фильтр области действия
\Bitrix\Main\Engine\ActionFilter\Scope
Блокирует действия для определенного scope. Полезен для ограничения доступа к действиям в зависимости от контекста выполнения, например, только для AJAX-запросов.
Аргументы:
$scopes— перечисление допустимых scopes.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\Scope;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new Scope(
Scope::AJAX | Scope::REST
),
])]
public function indexAction()
{
// ...
}
}
Имеет аналог в виде атрибута:
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[\Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Scope(
Scope::AJAX | Scope::REST
)]
public function indexAction()
{
// ...
}
}
Фильтр CORS-настроек
\Bitrix\Main\Engine\ActionFilter\Cors
Устанавливает заголовки для управления CORS. Используется для настройки CORS, когда требуется доступ к ресурсам с другого домена.
Аргументы:
-
$origin— заголовокAccess-Control-Allow-Origin. По умолчанию —null. -
$credentials— устанавливает заголовокAccess-Control-Allow-Credentials. По умолчанию —false.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Postfilters;
use Bitrix\Main\Engine\ActionFilter\Cors;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Postfilters([
new Cors()
])]
public function indexAction()
{
// ...
}
}
Имеет аналог в виде атрибута:
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[\Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Cors]
public function indexAction()
{
// ...
}
}
Фильтр типа контента
\Bitrix\Main\Engine\ActionFilter\ContentType
Разрешает выполнение действия только для допустимых content-type. Полезен для обеспечения корректной обработки данных в зависимости от типа контента, например, JSON.
Аргументы:
$allowedTypes— допустимые content-type.
Пример использования:
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\ContentType;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new ContentType([
'application/json',
])
])]
public function indexAction()
{
// ...
}
}
Как использовать фильтры в контроллерах
Указать фильтры для конкретных действий можно с помощью метода контроллера configureActions.
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\Cors;
final class Entity extends \Bitrix\Main\Engine\Controller
{
public function configureActions()
{
return [
'index' => [
'prefilters' => [
new Authentication(),
],
'postfilters' => [
new Cors(),
],
],
];
}
public function indexAction()
{
// ...
}
}
Тоже самое можно сделать с помощью атрибутов Prefilters и Postfilters.
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Postfilters;
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\Prefilters;
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\Cors;
final class Entity extends \Bitrix\Main\Engine\Controller
{
#[Prefilters([
new Authentication(),
])]
#[Postfilters([
new Cors(),
])]
public function indexAction()
{
// ...
}
}
Фильтры по умолчанию
По умолчанию все действия контроллера используют фильтры HttpMethod, Authentication и Csrf. Чтобы изменить такое поведение, нужно переопределить метод контроллера getDefaultPreFilters.
В примере ниже, все действия контроллера будут использовать фильтры Authentication и Cors.
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\Cors;
final class Entity extends \Bitrix\Main\Engine\Controller
{
protected function getDefaultPreFilters()
{
return [
new Authentication(),
];
}
protected function getDefaultPostFilters()
{
return [
new Cors(),
];
}
public function indexAction()
{
// ...
}
public function getAction()
{
// ...
}
}
Если использовать префильтры по умолчанию не нужно, передайте пустой массив.
final class Entity extends \Bitrix\Main\Engine\Controller
{
protected function getDefaultPreFilters()
{
return [];
}
}
Дополняющие и вычитающие фильтры
Чтобы гибко работать с фильтрами, можно включать и отключать различные фильтры с помощью префиксов + и - в configureActions().
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\CloseSession;
use Bitrix\Main\Engine\ActionFilter\Csrf;
final class Entity extends \Bitrix\Main\Engine\Controller
{
protected function getDefaultPreFilters()
{
return [
new Authentication(),
new Csrf(),
];
}
public function configureActions()
{
return [
// Итого для действия `index` будут применены фильтры: CloseSession и Csrf
'index' => [
'+prefilters' => [
new CloseSession()
],
'-prefilters' => [
Authentication::class,
],
],
];
}
public function indexAction()
{
// ...
}
}
И аналогично с использованием атрибутов EnablePrefilters и DisablePrefilters.
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\DisablePrefilters;
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\EnablePrefilters;
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\CloseSession;
use Bitrix\Main\Engine\ActionFilter\Csrf;
final class Entity extends \Bitrix\Main\Engine\Controller
{
protected function getDefaultPreFilters()
{
return [
new Authentication(),
new Csrf(),
];
}
#[EnablePrefilters([
new CloseSession(),
])]
#[DisablePrefilters([
Authentication::class,
])]
public function indexAction()
{
// ...
}
}
Аналогичным образом работает механика дополнения и вычитания для постфильтров.
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\DisablePostfilters;
use Bitrix\Main\Engine\ActionFilter\Attribute\Rule\EnablePostfilters;
use Bitrix\Main\Engine\ActionFilter\Cors;
final class Entity extends \Bitrix\Main\Engine\Controller
{
protected function getDefaultPostFilters()
{
return [
new Cors(),
];
}
public function configureActions()
{
return [
// Итого для действия `index` будут применен только фильтр AnotherPostFilter
'index' => [
'+postfilters' => [
new AnotherPostFilter(),
],
'-postfilters' => [
Cors::class,
],
],
];
}
public function indexAction()
{
// ...
}
#[EnablePostfilters([
new AnotherPostFilter(),
])]
#[DisablePostfilters([
Cors::class,
])]
public function getAction()
{
// ...
}
}
В случае дополнения фильтров нужно отправлять объект фильтра, а в случае вычитания — имя класса.
Подменить ответ через фильтр
Фильтры добавляют свои ошибки в контроллер. Пример работы с ошибками можно посмотреть в стандартном фильтре Bitrix\Main\Engine\ActionFilter\HttpMethod::onBeforeAction.
Фильтр может подменить результат через метод onAfterAction.
class CustomFilter extends \Bitrix\Main\Engine\ActionFilter\Base
{
public function onBeforeAction(\Bitrix\Main\Event $event)
{
// Решаем подменить ответ, возвращаем ошибку в обработчике ДО
return new EventResult(
EventResult::ERROR,
handler: $this,
);
}
public function onAfterAction(\Bitrix\Main\Event $event)
{
// В обработчике ПОСЛЕ подменяем результат
// Если вернуть объект HttpResponse, то он отдается как есть
// Иначе результат обернут в стандартный JSON
$customResponse = new \Bitrix\Main\HttpResponse();
$event->setParameter('result', $customResponse);
}
}
Обработчики событий вызываются в методе Bitrix\Main\Engine\Controller::run.