CakePHP-loginAction的绝对URL [英] CakePHP - Absolute URLs for loginAction

查看:102
本文介绍了CakePHP-loginAction的绝对URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我们设置AWS托管的方式,我必须对CakePHP的loginAction使用绝对URL。
当前,我的loginAction看起来像这样(现在不起作用)

Due to the way we've setup our AWS hosting, I have to use absolute URLs for CakePHP's loginAction. Currently, my loginAction looks like this (doesn't work now)

'loginAction' => array('controller' => 'users', 'action' => 'login'),

使用从HTTP重定向到HTTPS组合,我得到一个重定向循环。我可以通过设置一个绝对的URL来证明这一点(正常工作)

Combine that with a redirect from HTTP -> HTTPS I get a redirect loop. I can prove this by setting an absolute URL like this (works fine)

'loginAction' => array('https://foo.com'),

我以为我可以设置最后一个像这样的真实参数

I thought I could just set the final param to true like this

'loginAction' => array('controller' => 'users', 'action' => 'login', TRUE),

但这也不起作用。

我的最终失败是尝试设置类似这样的内容,

My final failure I tried setting something like this,

'loginAction' => "https://{$_SERVER['HTTP_HOST']}/users/login",

引发完全不相关的错误- PHP解析错误:语法错误,意外的''

Which throws a totally unrelated error - PHP Parse error: syntax error, unexpected '"'

我的问题是,


  • 我可以在loginAction()中设置绝对URL吗?

  • 或者我可以告诉Cake在某处始终使用绝对URL吗?例如,routes.php或bootstrap.php?

我见过人们在谈论FULL_BASE_URL和其他常量,但似乎没有任何帮助。

I've seen people talking about FULL_BASE_URL and other constants, none seem to help.

推荐答案

这是我们最近在设置AWS Elastic Beanstalk时遇到的确切问题。平衡器启动您的实例,它实际上使用PORT 80(http),并且如果您严格遵循以下流程:

This is our exact problem that we faced lately, when we set up AWS Elastic Beanstalk. The problem is that, when load balancer hits up your instance, it actually uses PORT 80 (http), and if you follow the flow closely:


  1. 您的 AuthComponent 使用 $ controller-> redirect()进行loginRedirect [ AuthComponent :: 419 ]

  2. redirect()使用 Router :: url($ loginRedirect,true)来获取完整的URL。 [控制器:: 774 ]

  3. Router :: url()使用 Router :: fullBaseUrl()来解析完整的基本网址[路由器:: 899 ]

  4. Router :: fullBaseUrl()使用 Configure :: read('App.fullBaseUrl' )来读取书面的完整基本url。 [路由器:: 929 ]

  1. Your AuthComponent uses $controller->redirect() to do the loginRedirect [AuthComponent::419]
  2. redirect() uses Router::url($loginRedirect, true) to get the full url. [Controller::774]
  3. Router::url() uses Router::fullBaseUrl() to resolve full base url [Router::899]
  4. Router::fullBaseUrl() uses Configure::read('App.fullBaseUrl') to read the written full base url. [Router::929]

所以问题是,谁解决了 fullBaseUrl

So the question is, who resolved fullBaseUrl?

进一步深入研究,您将在 Cake\bootstrap.php ,[罪魁祸首是该文件的第158行

Further digging it down, you will see that in Cake\bootstrap.php, [the culprit is in line 158 of that file

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 Load Balancer在端口80上命中了您的实例,而没有告诉您它是一个https调用(通常是这样),因此,cake被欺骗了,因为它是http,因此会导致重定向循环。

Got it? AWS Load balancer hits your instance on port 80 without telling you it's a https call (in the usual way), so cake is being fooled that it's http, and hence it results in redirection loops.

我们的解决方案很笨拙。由于我们正在使用弹性beantalk并且可以编辑环境变量,因此可以在 .ebextensions .config 文件中进行此操作。 >

Our solution is rather hacky. Since we are using elastic beanstalk and we can edit environment variables, we do this in our .config file in the .ebextensions

option_settings:
  - option_name: HTTPS
    value: 1

当我们根本不希望使用HTTP(并且始终使用https强制重定向)时,这很好。但是更好的是,也许使用 HTTP_X_FORWARDED _ * 变量来确定环境(如果您仍然需要http):

This is good when we don't want http at all (and always force redirection uses https). But what's better is, perhaps use the HTTP_X_FORWARDED_* variables to determine the environment (if you still need http):

如果您调试($ _SERVER),则应该可以看到以下内容:

If you debug($_SERVER), you should be able to see something like this:

["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 并在顶部添加以下行:

So this left you only one choice: Edit your bootstrap.php and add in this line on the top:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

一旦它尝试解析完整的基本URL,您将获得正确的协议设置。

And once it tries to resolve full base url, you will get the correct protocol set.

(或者,如果需要,您可以定义('FULL_BASE_URL'..),但我不知道't like it:p)

(Or, you could define('FULL_BASE_URL'..) if you want, but I don't like it :p)

注意

负载平衡世界,一切工作都略有不同。如果您的代码中的任何部分行为不正常,请始终检查 $ _ SERVER 数组。例如,您不应再依赖 $ _ SERVER ['REMOTE_ADDR'] 。您需要从 $ _ SERVER ['HTTP_X_FORWARDED_FOR'] 爆炸并检测该变量。

When we first entering this load balancing world, everything works slightly different. If any part of your code is not behaving like it should, always check the $_SERVER array. For example, you shouldn't rely on $_SERVER['REMOTE_ADDR'] anymore. You need to explode and detect this variable from $_SERVER['HTTP_X_FORWARDED_FOR'] instead.

编辑

如果出于安全考虑,请查看此线程。上面的技巧可能很方便,但不是防弹的: https://github.com/cakephp/cakephp / issues / 2035

Check out this thread if security is a concern. The above hack could be handy, but not bullet proof: https://github.com/cakephp/cakephp/issues/2035





基于CakePHP 2.4.1的答案,9月15日, 2013年,提交 085636ea1bb2a57b084456e776bfada01dee71df

这篇关于CakePHP-loginAction的绝对URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆