【環境】
AWS ElasticBeanstalkのPHP 5.3サーバ
LoadBalancerでSSLを設定し、80→80、443→80とした。
cakePHP 1.2 アプリケーション。
【現象】
https://???.elasticbeanstalk.com/blogs/first にアクセス
↓
アクション内で $this->redirect('/blogs/second');
↓
https://???.elasticbeanstalk.com/blogs/second へリダイレクトするはずが、
【原因】
レスポンスヘッダを確認すると、
Location: /blogs/second
ではなく、
Location: http://???.elasticbeanstalk.com/blogs/second
であった。
webブラウザからLoadBalancerへ443ポートアクセスしても、LoadBalancer配下のサーバには80ポートアクセスであり、環境変数 HTTPS は設定されない。そのためcakePHPはhttpアクセスと判断し、httpから始まるURLをFULL_BASE_URL定数を定義してしまう。
【対策例1】
cakePHPがFULL_BASE_URL定数を定義してしまう前に、アプリケーションでFULL_BASE_URL定数を定義する。
app/webroot/index.php の
「if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {」
より先頭側に次のスクリプトを挿入する。
function is_ssl_and_forwarded() { if ( isset($_SERVER['HTTP_X_FORWARDED_PORT']) && 443 == $_SERVER['HTTP_X_FORWARDED_PORT'] ) { $f = true; } else { $f =false; } return $f; } // is_ssl_and_forwarded if ( is_ssl_and_forwarded() ) { define( 'FULL_BASE_URL', 'https://' . $_SERVER['HTTP_HOST'] ); //var_dump( FULL_BASE_URL ); }
【対策例2】
.htaccess で、環境変数HTTPS を設定する。アプリケーション内で環境変数HTTPSを参照している全ての箇所でHTTPSと判断させることができる。
SetEnvIf x-forwarded-port "^443$" HTTPS=on
SetEnvIf x-forwarded-proto "^https$" HTTPS=on