3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CakePHP3でリバースプロキシ経由のアクセスだとCake\Routing\Router::urlのアドレスがプライベートIPになる

Last updated at Posted at 2018-10-29

開発環境では起こらなかったのですが、本番にデプロイしたところURLがプライベートIPになってしまいました。

問題のコード

src/Template/Layout/default.ctp

$this->assign('requestFullUrl', \Cake\Routing\Router::url(NULL, true));

テンプレートでCake\Routing\Router::urlを使ってカレントのURLを取得していました。
このURLをog:urlなどに設定していたのですが、本番でプライベートIPアドレスになったのでFacebookでシェアされた時にリンク切れになってしまいました。

原因調査

CakePHPのコードを見てみるとこちらのコードになっていました。

vendor/cakephp/cakephp/src/Routing/Router.php

    public static function url($url = null, $full = false)
    {
        ...

        if (empty($url)) {
            $output = isset($here) ? $here : $base . '/';
            if ($full) {
                $output = static::fullBaseUrl() . $output;
            }

            return $output;
        }

static::fullBaseUrl()という関数が呼び出されていて、ここに正しいドメインが指定できれば良さそうです。
更にコードを追ってみると。

vendor/cakephp/cakephp/src/Routing/Router.php
...
    /**  
     * Contains the base string that will be applied to all generated URLs
     * For example `https://example.com`
     *
     * @var string
     */
    protected static $_fullBaseUrl;
...
    public static function fullBaseUrl($base = null)
    {   
        if ($base !== null) {
            static::$_fullBaseUrl = $base;
            Configure::write('App.fullBaseUrl', $base);
        }
        if (empty(static::$_fullBaseUrl)) {
            static::$_fullBaseUrl = Configure::read('App.fullBaseUrl');
        }

        return static::$_fullBaseUrl;
    }

static::$_fullBaseUrlが空の時、config/app.phpファイルのApp.fullBaseUrlを代入するになってました。

解決方法

なので、下記の箇所を修正

config/app.php

    'App' => [
         'namespace' => 'App',
         'encoding' => env('APP_ENCODING', 'UTF-8'),
         'defaultLocale' => env('APP_DEFAULT_LOCALE', 'ja-JP'),
         'base' => false,
         'dir' => 'src',
         'webroot' => 'webroot',
         'wwwRoot' => WWW_ROOT,
         // 'baseUrl' => env('SCRIPT_NAME'),
-        'fullBaseUrl' => false,
+        'fullBaseUrl' =>  env('PROTOCOL', 'http')
+            . '://'. env('DOMAIN', 'localhost:8888'),
         'imageBaseUrl' => 'img/',

余談

念の為リファレンスを確認してみると下記のことが書かれています。
https://book.cakephp.org/3.0/ja/development/configuration.html

App.fullBaseUrl
アプリケーションのルートまでの (プロトコルを含む) 完全修飾ドメイン名です。 これは完全な URL を生成する際 に利用されます。デフォルトでは、この値は $_SERVER の環境情報から生成されます。しかし、パフォーマンスを最適化したり、 他人が Host ヘッダーを操作するのを心配するならば、自分で指定すべきでしょう。CLI 環境 (シェル) ではウェブサーバーとの関連が無いので fullBaseUrl を $_SERVER から読むことができません。もしシェルから URL を作成する必要がある場合 (例えばメールの送信) 、自力で指定する必要があります。

想定されていないわけ無いですよね・・・。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?