CodeIgniter和Ion Auth如何配置前后端分域

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

我正在对旧的 CodeIgniter 应用程序进行现代化改造。通过前后端分离应用。

新前端是一个 angular SPA 应用程序。后端仍然使用 CI 的应用程序。 CI 使用 Ion_Auth 授权用户。

如果两者都在同一个域中,一切正常,例如 localhost

问题是每个部分必须在不同的url域,即:

通过这种方式 Ion Auth 能够 log-in 用户,但是当我查询用户是否登录时,它 returns false。 CI 不再保留 session。

我还注意到,当两者都进入 相同域 时,session 文件夹仅包含一个文件,这意味着 CI 识别 session。

当我将其设置到 不同的域 时,session 文件夹会为每个 XHR 请求创建一个新文件。这意味着 CI 不再持有 session。

为什么会这样?我应该怎么做才能使前端和后端与 Ion Auth 正常工作?

这是我的 CI 配置:

$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();

我也设置了:

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

这就是我发出 XHR 请求的方式。

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

我刚在 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.

(特别强调句子中的NOT关键字)

我换句话说。无论如何都行不通。 XHR 请求中必须存在一个特殊标志。当使用 AngularJS $hhtp object 我必须使用 withCredentials: true

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

还需要在 API 回复中同时设置 headers:

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

不幸的是,我无法将*用作Access-Control-Allow-Origin,我必须使用正确的域。

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

通过这种方式,我能够使用保留会话的 cookie 进行跨源 XHR 请求。