Search code examples
phpcodeigniter-4

Codeigniter 4 csrf filter for post methods in given area only


app/Config/Filters.php

You can set filter for all post methods

public $methods = [
    'post' => ['filter'],
];

Or you can set a filter for a given area (but all methods)

public $filters = [
    'filter' => ['before' => ['account/*', 'profiles/*']]
];

How can I set a filter for only post methods in a given area? Or even better in all areas except one?

I know it is possible for individuals endpoint routes, but I am hoping to find more of a global solution..


Solution

  • How about this, not tested but it should work.

    Create a new filter which extended from CSRF and checks request method

    namespace App\Filters;
    
    use CodeIgniter\Filters\CSRF;
    use CodeIgniter\Filters\FilterInterface;
    use CodeIgniter\HTTP\RequestInterface;
    use CodeIgniter\HTTP\ResponseInterface;
    use Config\Services;
    use Exception;
    
    class CustomCSRF extends CSRF implements FilterInterface
    {
        public function before(RequestInterface $request, $arguments = null)
        {
            $request = parent::before($request, $arguments);
            try {
                if ($request->getMethod() != "post") {
                    throw new Exception("Wrong method");
                }
            } catch (Exception $e) {
                return Services::response()
                    ->setJSON([
                        'error' => $e->getMessage()
                    ])
                    ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
            }
            return $request;
        }
    }
    

    then add it under filters for routes

    public $aliases = [
        ...
        ...
        'customcsrf' => CustomCSRF::class
    ];
    
    ...
    ...
    
    public $filters = [
        'customcsrf' => ['before' => ['account/*', 'profiles/*']]
    ];