由于我们设置AWS托管的方式,我必须使用CakePHP的loginAction的绝对URL。 目前,我的loginAction看起来像这样(现在不起作用)
'loginAction' => array('controller' => 'users', 'action' => 'login'),
将其与来自HTTP的重定向相结合 - > HTTPS我得到一个重定向循环。我可以通过设置这样的绝对URL来证明这一点(工作正常)
'loginAction' => array('https://foo.com'),
我以为我可以将最终的参数设置为真如此
'loginAction' => array('controller' => 'users', 'action' => 'login', TRUE),
但这也不起作用。
我最后的失败我尝试过这样的设置,
'loginAction' => "https://{$_SERVER['HTTP_HOST']}/users/login",
抛出一个完全不相关的错误 - PHP Parse错误:语法错误,意外'''
所以我的问题是,
我见过有人在谈论FULL_BASE_URL和其他常数,似乎没有人帮忙。
答案 0 :(得分:4)
这是我们最近在设置AWS Elastic Beanstalk时遇到的确切问题。问题在于,当负载均衡器命中您的实例时,它实际上使用PORT 80(http),如果您密切关注流程:
AuthComponent
使用$controller->redirect()
来执行loginRedirect [AuthComponent::419] redirect()
使用Router::url($loginRedirect, true)
获取完整网址。 [Controller::774] Router::url()
使用Router::fullBaseUrl()
来解析完整的基本网址[Router::899] Router::fullBaseUrl()
使用Configure::read('App.fullBaseUrl')
来阅读已写入的完整基本网址。 [Router::929] 所以问题是,谁解决了fullBaseUrl
?
进一步挖掘它,你会在Cake\bootstrap.php
中看到,[罪魁祸首在该档案的第158行
if (!defined('FULL_BASE_URL')) {
$s = null;
if (env('HTTPS')) { <---------------- @@@@ env('HTTPS') is false!!!! @@@@
$s = 's';
}
$httpHost = env('HTTP_HOST');
if (isset($httpHost)) {
define('FULL_BASE_URL', 'http' . $s . '://' . $httpHost);
Configure::write('App.fullBaseUrl', FULL_BASE_URL);
}
unset($httpHost, $s);
}
知道了吗? AWS负载均衡器在端口80上点击你的实例而不告诉你它是一个https调用(以通常的方式),所以蛋糕被愚弄它的http,因此它导致重定向循环。
我们的解决方案相当hacky。由于我们使用弹性beanstalk并且我们可以编辑环境变量,因此我们在.config
.ebextensions
文件中执行此操作
option_settings:
- option_name: HTTPS
value: 1
当我们根本不想要http时(这总是强制重定向使用https)这很好。但更好的是,也许使用HTTP_X_FORWARDED_*
变量来确定环境(如果你仍然需要http):
如果你debug($_SERVER)
,你应该可以看到类似的内容:
["HTTP_X_FORWARDED_FOR"]=>"xx.xx.xx.xx, xx.xx.xx.xx, ...." //note that the first is IP, the rest are proxies
["HTTP_X_FORWARDED_PORT"]=>"443"
["HTTP_X_FORWARDED_PROTO"]=>"https"
所以这只留下一个选择:编辑bootstrap.php
并在顶部添加以下内容:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
一旦尝试解析完整的基本网址,您将获得正确的协议集。
(或者,你可以define('FULL_BASE_URL'..)
如果你愿意,但我不喜欢它:p)
注意强>
当我们第一次进入负载平衡世界时,一切都有所不同。如果代码的任何部分行为不正常,请始终检查$_SERVER
数组。例如,您不应再依赖$_SERVER['REMOTE_ADDR']
了。您需要从$_SERVER['HTTP_X_FORWARDED_FOR']
爆炸并检测此变量。
修改强>
如果担心安全问题,请查看此主题。上面的黑客可能很方便,但不能防弹:https://github.com/cakephp/cakephp/issues/2035
2013年9月15日基于CakePHP 2.4.1的回答,提交085636ea1bb2a57b084456e776bfada01dee71df