Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Фильтры

Фильтр — класс, код которого выполняется до контроллера или после него. До контроллера проверяют, вошёл ли посетитель и есть ли у него права; после — дополняют готовый ответ, например заголовками. Один фильтр подключают сразу ко многим адресам, и проверку не приходится повторять в каждом методе. Фильтры лежат в папке app/Filters.

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

php spark make:filter AuthFilter

Команда создаёт файл app/Filters/AuthFilter.php с двумя методами. Заполните первый:

// app/Filters/AuthFilter.php
namespace App\Filters;
 
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
 
class AuthFilter implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null)
    {
        if (! session()->has('user_id')) {
            return redirect()->to('/login');
        }
    }
 
    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
    }
}

Метод before() выполняется до контроллера. Если он возвращает ответ — здесь перенаправление, — контроллер не вызывается. Если ничего не возвращает, запрос идёт дальше.

Регистрация

Фильтру дают короткое имя в свойстве $aliases файла app/Config/Filters.php:

// app/Config/Filters.php
public array $aliases = [
    'csrf' => \CodeIgniter\Filters\CSRF::class,
    // остальные строки оставьте как есть
    'auth' => \App\Filters\AuthFilter::class,
];

Подключение к маршруту

Имя фильтра указывают в третьем аргументе маршрута:

// app/Config/Routes.php
$routes->get('posts/new', 'Posts::new', ['filter' => 'auth']);

Откройте /posts/new: в сессии нет user_id, поэтому браузер перейдёт на /login. Остальные адреса работают как прежде.

Фильтр для группы

Чтобы закрыть целый раздел, фильтр подключают к группе маршрутов:

$routes->group('admin', ['filter' => 'auth'], static function ($routes) {
    $routes->get('posts', 'Admin\Posts::index');
    $routes->get('users', 'Admin\Users::index');
});

Все адреса, начинающиеся с /admin, проходят через фильтр.

Метод after

Метод after() получает готовый ответ и может его изменить:

public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
    return $response->setHeader('X-Frame-Options', 'DENY');
}

Заголовок добавится ко всем ответам, прошедшим через фильтр.

Фильтры для всех запросов

Свойство $globals в app/Config/Filters.php перечисляет фильтры, которые работают на каждом адресе:

КлючКогда выполняется
beforeДо контроллера: csrf, honeypot
afterПосле контроллера: toolbar, secureheaders

Именно так в уроке о формах включалась проверка CSRF.

Частая ошибка

Фильтр auth, подключённый ко всем адресам вместе со страницей входа, создаёт бесконечное перенаправление: гость попадает на /login, фильтр снова отправляет его на /login, и браузер сообщает о слишком большом числе переходов. Подключайте фильтр только к закрытым маршрутам, а страницы входа и регистрации оставляйте открытыми.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.