Home > Net >  My API Is Blocked By Filters When Request Method Is POST CI4
My API Is Blocked By Filters When Request Method Is POST CI4

Time:03-18

I am building a Web App along with API for Android using CI4.

For the Web App, I have a filter to check whether the user already logged in with some exceptions, one of them is to ignore the filter if the URL consists api/* (The url for API is http://localip/api/)

The API is working fine if the request method is GET. I can get the data from API. But when I tried to insert a data to database using POST method, it redirects me to login page (I'm using Postman to test the API)

How do I fix this?

What I have tried so far was adding login filter alias to

public $methods = [
        'post' => ['csrf', 'loginfilter']
    ]; But still not working

Here is the full code

Filters.php

<?php

namespace Config;

use App\Filters\CorsFilter;
use App\Filters\LoginFilter;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Filters\CSRF;
use CodeIgniter\Filters\DebugToolbar;
use CodeIgniter\Filters\Honeypot;
use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\SecureHeaders;

class Filters extends BaseConfig
{
    /**
     * Configures aliases for Filter classes to
     * make reading things nicer and simpler.
     *
     * @var array
     */
    public $aliases = [
        'loginfilter' => LoginFilter::class,
        'cors' => CorsFilter::class
    ];

    /**
     * List of filter aliases that are always
     * applied before and after every request.
     *
     * @var array
     */
    public $globals = [
        'before' => [
            // 'honeypot',
            'csrf',
            'loginfilter' => ['except' => ['/', '/login', 'api/*']],
            'cors'
            // 'invalidchars',
        ],
        'after' => [
            'toolbar',
            // 'honeypot',
            // 'secureheaders',
        ],
    ];

    /**
     * List of filter aliases that works on a
     * particular HTTP method (GET, POST, etc.).
     *
     * Example:
     * 'post' => ['csrf', 'throttle']
     *
     * @var array
     */
    public $methods = [
        'post' => ['csrf','loginfilter]
    ];

    /**
     * List of filter aliases that should run on any
     * before or after URI patterns.
     *
     * Example:
     * 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']]
     *
     * @var array
     */
    public $filters = [];
}

LoginFilter.php

<?php

namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class LoginFilter implements FilterInterface
{

    public function before(RequestInterface $request, $arguments = null)
    {
        $session = session();
        if (!$session->has('user_id')) {
            return redirect()->to(base_url() . '/');
        }
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
    }
}

Routes.php

$routes->resource("api/role", ['controller' => 'apis\MasterDataRoleApi']);

MasterDataRoleApi.php (Controller)

<?php

namespace App\Controllers\apis;

use App\Models\GeneralModels;
use App\Models\RoleModel;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\RESTful\ResourceController;

class MasterDataRoleApi extends ResourceController
{
    use ResponseTrait;
    protected $model;
    protected $generalModel;

    public function __construct()
    {
        $this->model = new RoleModel();
        $this->generalModel = new GeneralModels();
    }

    public function index()
    {
        $role= $this->request->getVar('role');
        $data = $this->model->getRoleApi($role);
        return $this->respond($data, 200);
    }

    public function create()
    {
        $roleName = $this->request->getPost('role_name');
        $supervisor = $this->request->getPost('supervisor');
        $userId = $this->request->getVar("userId");
        helper('idgenerator');
        $maxCode = $this->generalModel->getMaxData('tmrole', 'role_id');
        $generatedId = idGenerator($maxCode[0]['role_id'], 4, 3, "JAB-");

        $this->model->insertTmRole($generatedId, $roleName, $userId, $userId);
       

        $data = array();

        $dataArr = array(
            "response" => "Success",
            "response_details" => "Saved Successfully"
        );

        $data[] =  $dataArr;

        return $this->respondCreated($data, 201);
    }
}

Image below shows Json returned when request method is GET enter image description here

The X-CSRF-TOKEN HTTP request header value should be the same as the csrf_cookie_name cookie value.

HTTP Request Call Requirements:

I.e:

POST http://myapp.local/api/companies

Request Body. Don't forget to add the csrf_cookie_name token as part of the request body.

Key Value
company_name Tesla, Inc.
csrf_cookie_name 62b04a891414ef789bee7108f94ad97a

As I conclude with PART B:

Important items Description
ci_session cookie or an Authorization: Bearer xxxxxxx header. Allows you to authenticate with your application/project only for Auth protected API endpoints. In your particular case, I believe your loginfilter is working with a ci_session cookie and the cookie is expected to be sent along with every request with the help of the Cookie HTTP request header.
csrf_cookie_name cookie and (a X-CSRF-TOKEN header or CSRF token request parameter). The CSRF cookie and (X-CSRF-TOKEN header or CSRF token request parameter) values MUST match. This is a requirement if you've turned on the csrf filter.
  • Related