Search code examples
codeignitersessioncookiessession-cookiesion-auth

How to configure CodeIgniter and Ion Auth with front and back ends into different domains


I'm working on a modernization of and old CodeIgniter Application. By separateing the application in front and back ends.

The new Front end is an angular SPA application. The backend still uses a of CI application. The CI uses Ion_Auth to authorize users.

Everything works fine if both are into the same domain, for instance localhost

The problem is that each part must be on different url domains, ie.:

  • Frontend - localhost:8081, in the future will be example.com
  • Backend - localhost:8082, in the future will be api.example.com

This way Ion Auth is able to log-in users, but when I query if user is logged in, it returns false. The CI doesent holds the session anymore.

I also noted that when both are into the same domain the session folder only contains only one file, which means that CI recognizes the session.

When I set it onto different domains, the session folder creates a new file for each XHR Request. That means that CI is not holding session anymore.

Why this is happening? What Should I do to make front and backend to work properly with Ion Auth?

Here are my CI configuration:

$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = BASEPATH . 'var/session/';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;

$config['cookie_prefix']    = '';
$config['cookie_domain']    = '';
$config['cookie_path']      = '/';
$config['cookie_secure']    = FALSE;
$config['cookie_httponly']  = FALSE;

$config['csrf_protection'] = FALSE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();

I also set :

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");

And this is how I'm making the XHR requests.

$http({
  url: $rootScope.API_URL + "/user/check",
  method: "POST",
  headers: { "Content-Type": undefined },
  data: { /*...*/ }
}).then( /*...*/ )

Solution

  • I Just found at https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#section_5

    The most interesting capability exposed by both XMLHttpRequest or Fetch and CORS is the ability to make "credentialed" requests that are aware of HTTP cookies and HTTP Authentication information. By default, in cross-site XMLHttpRequest" or Fetch invocations, browsers will not send credentials. A specific flag has to be set on the XMLHttpRequest" object or the Request constructor when it is invoked.

    (Special Highlight to the NOT keyword in the sentence).

    I other words. It will no work anyway. A special flag must be present in the XHR request. When using AngularJS $hhtp object I must use withCredentials: true

    $http({
      url: ...
      withCredentials: true
    })
    

    Also need to set both headers in API responses:

    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: http://localhost
    

    Unfortunately I was not able to use* as Access-Control-Allow-Origin, instead I must use the correct domains.

    'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

    This way I was able to make Cross origin XHR Requests with cookies preserving sessions.