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
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. |