Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Filters

A filter is a class whose code runs before the controller or after it. Before the controller you check whether the visitor is logged in and has permission; after it you add to the finished response, for example headers. One filter is attached to many addresses at once, so the check is not repeated in every method. Filters live in the app/Filters folder.

Creating a filter

php spark make:filter AuthFilter

The command creates the file app/Filters/AuthFilter.php with two methods. Fill in the first one:

// 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)
    {
    }
}

The before() method runs before the controller. If it returns a response — a redirect here — the controller is not called. If it returns nothing, the request goes on.

Registration

A filter gets a short name in the $aliases property of app/Config/Filters.php:

// app/Config/Filters.php
public array $aliases = [
    'csrf' => \CodeIgniter\Filters\CSRF::class,
    // leave the other lines as they are
    'auth' => \App\Filters\AuthFilter::class,
];

Attaching to a route

The filter name goes into the third argument of a route:

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

Open /posts/new: the session has no user_id, so the browser goes to /login. Other addresses work as before.

A filter for a group

To close a whole section, attach the filter to a route group:

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

Every address starting with /admin passes through the filter.

The after method

The after() method receives the finished response and may change it:

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

The header is added to every response that passes through the filter.

Filters for all requests

The $globals property in app/Config/Filters.php lists the filters that work on every address:

KeyWhen it runs
beforeBefore the controller: csrf, honeypot
afterAfter the controller: toolbar, secureheaders

This is how the CSRF check was switched on in the forms lesson.

Common mistake

An auth filter attached to every address including the login page creates an endless redirect: a guest lands on /login, the filter sends them to /login again, and the browser reports too many redirects. Attach the filter only to protected routes and leave the login and registration pages open.

Thanks for reading!

Donate to the site — we work hard for you.