2013年 5月 5

問題点

この問題は Mojoliciousでhttps(SSL)専用ページとhttp専用ページの振り分けをroutesのbridgeを使って行うを実装した時に起こる問題です。

件のエントリーの実装でもスタンドアロンのサーバで公開する場合には問題にならないのですが、Nginx等のリバースプロクシの後ろにアプリケーションサーバを置いて運用する場合に問題が起きます。

通常、webサーバであるNginxとクライアントの間ではSSL通信を行い、バックエンドのアプリケーションサーバ(Starman等)とNginxの間では通常のhttpで通信すると思います。

           SSL通信
クライアント   ---   Nginx
                     |     http通信
                   Starman

この場合だと、件のエントリーの

  # SSL onry routes
  my $ssl_rotes = $routes->bridge->to(
    cb => sub{
      my $self = shift;
 
      my $req = $self->req;
      return 1 if $req->is_secure;
      
      $self->redirect_to($req->url->to_abs->scheme('https'));
      return;
    }
  );

ようにschemeで判定してhttps~にリダイレクトする場合、Nginxとアプリケーションは常にhttpで通信しているのでリダイレクトが無限ループしてしまいます。

Nginxとアプリケーション間をSSLにすればよいのですが、(アプリケーション側の)ポートを開けたり指定しなくてはならなくなったりと色々面倒なことになりそうです…。

対策

Nginxの設定でリダイレクトを使うか、SSLの場合はリンクをhttpsで指定するかしか無さそう。

例えばstartupの中で下記のようなhelperを定義して、

  # helper method
  $self->helper(
    url_for_http => sub {
      my $self = shift;      
      my $url = $self->url_for(@_)->to_abs->scheme('http');
      return $url;
    }
  );
  $self->helper(
    url_for_https => sub {
      my $self = shift;      
      my $url = $self->url_for(@_)->to_abs->scheme('https');
      return $url;
    }
  );

templateで

<%= link_to url_for_http('/') => begin %>httpを強要<% end %>
<%= link_to url_for_https('/ssl_onry') => begin %>セキュアなページへのリンク<% end %>

のように使うしか無いのかな。

More from my site


Filed under: Mojolicious

Trackback Uri


2 Comments.

  • hypnotoadの設定ファイルでバースプロキシの設定を行って{proxy => 1}

    Nginxのリバースプロキシの設定で

    proxy_set_header X-Forwarded-HTTPS 1;

    とすれば解決するかもしれません。

  • clicktx says:

    ありがとうございます!実はつい最近perlcodesampleさんの該当のエントリーを読んで解決するかもしれないと思って、はてぶしてそのままになってます^^;

    リバースプロキシからSSL通信であることを伝える / Mojoliciousリファレンス – サンプルコードによるPerl入門
    http://d.hatena.ne.jp/perlcodesample/20130527/1369615777

    試してみたいと思います!



コメントする