Welcome Guest, Not a member yet? Register   Sign In
API Route not wokring
#1

Dear All,
Could any one please help ? 
I am using CI4 to build rest API. But, I cannot protect API route if I turned AutoRoute to FALSE my frontend cannot send POST method with Cross Origin Resource Sharing to my API.
I try to allow all header origin and all API methods with Filter But, it's not working if AutoRoute turned to False.
if I turned Auto Route to True. Everything works fine with Cross Origin Resource Sharing But, I cannot protect the Route with filter. Because When try to send POST method to get the route that defined with get Method it's still can fetch data and nothing can protected AutoRoute.
example: I turned AutoRoute to True. I defined method $route->get('/users','User::index',['Filter'=>'AuthFilter']);

But, I send POST method to my_web_url/users the system still response data back to client without any crediential.
Reply
#2

If you share your route table it might be easier to help.
For rest API's you should use the 'API Response Trait' library. Read more here https://codeigniter.com/user_guide/outgo...t=resource
Reply
#3

PHP Code:
Dear FriendsPlease see my below php code and help me please

1. Controller 
for fetch all users 
Code:
<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;
use App\Models\UserModel;


class User extends BaseController
{
    use ResponseTrait;
    public function index()
    {
        $users = new UserModel;
        return $this->respond($users->findAll(), 200);
    }
}

2.  This is My  Cors filter
Code:
<?php

namespace App\Filters;

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

class CorsFilter implements FilterInterface
{
   
    public function before(RequestInterface $request, $arguments = null)
    {
        header('Access-Control-Allow-Origin: *');
        header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
        header("Access-Control-Allow-Methods:  GET,POST, OPTIONS, PUT, DELETE");
        $method = $_SERVER['REQUEST_METHOD'];
        if ($method == "OPTIONS") {
            die();
        }
    }

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

3. This is my AuthFilter
Code:
<?php

namespace App\Filters;

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

class AuthFilter implements FilterInterface
{
   
    public function before(RequestInterface $request, $arguments = null)
    {
        $key = getenv('JWT_SECRET_KEY');
        $header = $request->getHeader("Authorization");
        $token = null;

        // extract the token from the header
        if(!empty($header)) {
            if (preg_match('/Bearer\s(\S+)/', $header, $matches)) {
                $token = $matches[1];
            }
        }

        // check if token is null or empty
        if(is_null($token) || empty($token)) {
           
            $data=[
                'status'=>false,
                'message'=>'Unauthorized'
            ];
            $response = service('response');
            $response->setJSON($data);
            $response->setStatusCode(401);
            return $response;
        }

        try {
            $decoded = JWT::decode($token, $key, array("HS256"));
       
        } catch (\Firebase\JWT\ExpiredException $ex) {

            $data=[
                'status'=>false,
                'message'=>'Unauthorized, Invalid Token'
            ];
            $response = service('response');
            $response->setJSON($data);
            $response->setStatusCode(401);
            return $response;

        }
    }

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


4. And this is Global Filters Config
Code:
public $aliases = [
      //  'csrf'    => CSRF::class,
      //  'toolbar'  => DebugToolbar::class,
      //  'honeypot' => Honeypot::class,
        'authFilter' => \App\Filters\AuthFilter::class,
        'CorsFilter'=>\App\Filters\CorsFilter::class
    ];

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

5. The last if My Route config
Code:
*/
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Home');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
$routes->setAutoRoute(true);

/*
* --------------------------------------------------------------------
* Route Definitions
* --------------------------------------------------------------------
*/

// We get a performance increase by specifying the default
// route since we don't have to scan directories.
$routes->get('/', 'Home::index');

$routes->group("api", function ($routes) {
    $routes->post("register", "Register::index");
    $routes->post("login", "Login::index");
    $routes->get("users", "User::index", ['filter' => 'authFilter']);
  
});

So, my problem is when I set Autoroute to TRUE my cors (Cross Site ) can work. But I cannot protect my route because when users known the there is controller named "User" the user just use post or get method to myweb_url/user/index and the system still fetch all information.

But, if i set Autoroute to false i can protect my route but My Cors filter not working. So, I cannot calls my API from another domain.
Reply
#4

Good read on CORS

Cross-Origin Resource Sharing (CORS)
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#5

Dear Sir,
Thanks for your support. But, I am still cannot solved this.
Reply
#6

(This post was last modified: 01-10-2022, 05:44 AM by iRedds.)

@InsiteFX gave a good link, but you probably read it inattentively.

Any CORS response must contain the "Access-Control-Allow-Origin" header.
Your CorsFilter should look like this.

PHP Code:
public function before(RequestInterface $request$arguments null)
{
    
Services::response()->setHeader('Access-Control-Allow-Origin','*');

    if (
strtolower($request->getMethod()) === 'options') {
        return 
Services::response()
            ->
setHeader("Access-Control-Allow-Headers",
                [
                    
'X-API-KEY',
                    
'Origin',
                    
'X-Requested-With',
                    
'Content-Type',
                    
'Accept',
                    
'Access-Control-Request-Method',
                    
'Authorization',
                ])
            ->
setHeader("Access-Control-Allow-Methods", ['GET''POST''OPTIONS''PUT''DELETE']);
    }

Reply
#7

Note sure if this would work but why don't you create a sperate routes for each using 'resources' and switch off Autoroutes

$routes->resource('register',['only' => ['index', 'show','create']]);

this way you can limit the method for each (POST,GET...etc).
Reply
#8

Dear All,
Thank you very much for your kind support. Finally, I have fixed my Cors problem by add these code to index.php and no need CorsFilter anymore.
PHP Code:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$method $_SERVER['REQUEST_METHOD'];
if(
$method == "OPTIONS") {
    die();

Reply
#9

"Access-Control-Allow-Origin: *" is probably bad practice.
Reply
#10

As @kenjis mentioned above, you should never use the * you should use your web site url ( https://www.your.com )
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply




Theme © iAndrew 2016 - Forum software by © MyBB