CakePHP - Absolute URLs for loginAction

你离开我真会死。 提交于 2019-12-10 18:03:39

问题


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'),

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),

but that doesn't work either.

My final failure I tried setting something like this,

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

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

So my questions are,

  • Can I set an absolute URL in loginAction()
  • Or, can I tell Cake to always use an absolute URL somewhere like, routes.php or bootstrap.php?

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


回答1:


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. 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]

So the question is, who resolved fullBaseUrl?

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);
}

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.

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

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):

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"

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';
}

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

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

Note

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.

EDIT

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




Answer based on CakePHP 2.4.1 on September 15, 2013, commit 085636ea1bb2a57b084456e776bfada01dee71df



来源:https://stackoverflow.com/questions/18805437/cakephp-absolute-urls-for-loginaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!