-
wolverine4277 Junior Member
 
-
Posts: 11
Threads: 4
Joined: Apr 2024
Reputation:
0
03-27-2025, 11:46 AM
(This post was last modified: 03-27-2025, 12:06 PM by wolverine4277.)
Hi, a few days ago I finished an API and after testing it a little bit I published it for a coworker to test it from his terminal.
The issue is that having the API on a server and the html/javascript that consumes the API appeared the problem with CORS.
If I don't use authorization (Bearer {token}) everything works fine, when I add a filter for JWT it stops working.
From this I started to do the configurations indicated in https://codeigniter.com/user_guide/libraries/cors.html whitout success!
<Cors.php>
PHP Code: public array $api = [ 'allowedOrigins' => ['http://localhost'], 'allowedOriginsPatterns' => [], 'supportsCredentials' => false, 'allowedHeaders' => ['Authorization', 'Content-Type'], 'exposedHeaders' => [], 'allowedMethods' => ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'], 'maxAge' => 7200, ];
<Routes.php>
PHP Code: $routes->group('', ['filter' => ['cors:api']], static function (RouteCollection $routes): void { $routes->resource('client', ['controller' => 'ClientController']); $routes->options('client', static function () {}); $routes->options('client/(:any)', static function () {}); });
PHP Code: CodeIgniter v4.6.0 Command Line Tool - Server Time: 2025-03-27 18:20:17 UTC+00:00
+---------+------------------+------+----------------------------------------------+------------------+---------------+ | Method | Route | Name | Handler | Before Filters | After Filters | +---------+------------------+------+----------------------------------------------+------------------+---------------+ | GET | client | » | \App\Controllers\ClientController::index | authjwt cors:api | cors:api | | GET | client/new | » | \App\Controllers\ClientController::new | authjwt cors:api | cors:api | | GET | client/(.*)/edit | » | \App\Controllers\ClientController::edit/$1 | authjwt cors:api | cors:api | | GET | client/(.*) | » | \App\Controllers\ClientController::show/$1 | authjwt cors:api | cors:api | | POST | client | » | \App\Controllers\ClientController::create | authjwt cors:api | cors:api | | PATCH | client/(.*) | » | \App\Controllers\ClientController::update/$1 | authjwt cors:api | cors:api | | PUT | client/(.*) | » | \App\Controllers\ClientController::update/$1 | authjwt cors:api | cors:api | | DELETE | client/(.*) | » | \App\Controllers\ClientController::delete/$1 | authjwt cors:api | cors:api | | OPTIONS | client | » | (Closure) | authjwt cors:api | cors:api | | OPTIONS | client/(.*) | » | (Closure) | authjwt cors:api | cors:api | +---------+------------------+------+----------------------------------------------+------------------+---------------+
Required Before Filters: forcehttps,pagecache
Required After Filters: pagecache, performance, toolbar
Also try something like this:
PHP Code: $routes->group('', ['filter' => 'cors'], static function (RouteCollection $routes): void { $routes->resource('client');
$routes->options('client', static function () { // Implement processing for normal non-preflight OPTIONS requests, // if necessary. $response = response(); $response->setStatusCode(204); $response->setHeader('Allow:', 'OPTIONS, GET, POST, PUT, PATCH, DELETE');
return $response; }); $routes->options('client/(:any)', static function () {}); });
without luck!
If I comment the line 'authjwt' => ['except' => ['/']], in Filters.php all works fine:
<Filters.php>
PHP Code: public array $globals = [ ... 'authjwt' => ['except' => ['/']], ...
The code of JWT filter is like this:
<AuthJwtFilter.php>
PHP Code: namespace App\Filters;
use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\Filters\FilterInterface;
class AuthJWTFilter implements FilterInterface { public function before(RequestInterface $request, $arguments = null) { // Get the Authorization header $authHeader = $request->getHeader('Authorization'); if (!$authHeader) { return $this->unauthorizedResponse(); }
// Extract the token from the header $token = str_replace('Bearer ', '', $authHeader->getValue());
// Validate the token (you can implement your own validation logic here) if (!$this->isValidToken($token)) { return $this->unauthorizedResponse(); } }
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { // Do something after the request is processed }
private function isValidToken($token) { // Implement your token validation logic here // For example, check against a database or decode a JWT
return $token === env('auth.JWT'); // Testing code, not the real one }
private function unauthorizedResponse() { return service('response') ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED) ->setJSON(['error' => 'Authentication is required.']); } }
The code on client es like this:
PHP Code: const token = 'token'; fetch('http://mydomain.com/myproject/client', { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); } return response.json(); }) .then(data => { const dataDiv = document.getElementById('data'); dataDiv.innerHTML = `<p>${JSON.stringify(data)}</p>`; }) .catch(error => { console.error('There was a problem with the fetch operation:', error); });
Image with error
I'm probably getting something wrong but I don't realize it.
Can someone help me?
Regards.
-
luckmoshy Do Codeigniter before do you!
   
-
Posts: 290
Threads: 55
Joined: Nov 2020
Reputation:
10
03-28-2025, 07:48 AM
(This post was last modified: 03-28-2025, 07:49 AM by luckmoshy.)
Your issue is here you can use '/' to mean that from the / routes, PHP Code: 'authjwt' => ['except' => ['/']],
= Code: 'authjwt' => ['except' => ['api/*']],
Codeigniter First, Codeigniter Then You!!
yekrinaDigitals
-
wolverine4277 Junior Member
 
-
Posts: 11
Threads: 4
Joined: Apr 2024
Reputation:
0
03-28-2025, 11:55 AM
(This post was last modified: 03-28-2025, 11:59 AM by wolverine4277.)
(03-28-2025, 07:48 AM)luckmoshy Wrote: Your issue is here you can use '/' to mean that from the / routes,
PHP Code: 'authjwt' => ['except' => ['/']],
=
Code: 'authjwt' => ['except' => ['api/*']],
Hi luckmoshy.
I tried what you suggested but it didn't work.
I recently started using CodeIgniter, so I may be wrong, but I understand that by doing the modification you indicated what I configure is that I do not apply the authjwt filter to everything that starts with api.
The urls that I use are like:
None url have api in the path.
Regards.
-
wolverine4277 Junior Member
 
-
Posts: 11
Threads: 4
Joined: Apr 2024
Reputation:
0
After reviewing the code I think I found the problem, the authjwt filter was applied before the cors filter.
When I modified that the API started to work when the correct jwt was sent (returning code 200) but did not work when an incorrect jwt was sent (returning code 401, which is correct, but I do not have access to the json response as CORS Missing Allow Origin is indicated.
What I did was to modify the function that returns the response adding the headers in the AuthJwtFilter:
PHP Code: private function unauthorizedResponse() { return service('response') ->setHeader('Access-Control-Allow-Origin', 'http://localhost') // Change this to your frontend URL ->setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type') ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED) ->setJSON(['error' => 'Authentication is required.']); }
and after that it was working.
Is it right to do it this way?
Or you should access the cors configuration and do something like this?
PHP Code: $response = service('response');
// Set CORS headers $corsConfig = config('CORS'); $allowedOrigins = $corsConfig->api['allowedOrigins']; $allowedHeaders = $corsConfig->api['allowedHeaders']; $origin = $request->getHeaderLine('Origin'); if (in_array($origin, $allowedOrigins)) { $response->setHeader('Access-Control-Allow-Origin', $origin); $response->setHeader('Access-Control-Allow-Headers', $allowedHeaders); }
// Set the response status and message return $response ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED) ->setJSON(['error' => 'Authenticatin is required.']);
Or is a better option? I feel like I'm repeating code...
Regards.
Translated with DeepL.com (free version)
|