8

I've written a web application using Catalyst that has a lot of forms and needs to run over https. There are no hard-coded URLs, everything uses $c->uri_for or $c->req->uri. Everything worked great in the development environment using the dev server running over http.

Today, when I went ahead and deployed the application, I noticed a problem. The way our production environment is currently setup, client browsers talk to a F5 load-balancer over HTTPS and the F5 talks to the web server on the internal network over HTTP.

[ Browser ] ---HTTPS---> [ F5 ] ---HTTP---> [ Web Server ]

Now, because the web server only gets HTTP requests, all URIs are generated starting with HTTP. This means:

<form action='[% c.uri_for('/secure/form') %]' method='post'>

becomes:

<form action='http://websitename.org/secure/form' method='post'>

and now all browsers complain you are submitting data over an insecure connection. I need that c.uri_for to begin with https.

The app needed to go live today, so I did a mass search/replace for all form actions to this:

<form action='[% c.uri_for('/secure/form') | replace('http:', 'https:'%]' method='post'>

Well, now that breaks development, so I conditionalized the form actions based on a config key:

[% IF c.config.production %]
  <form action='[% c.uri_for('/secure/form') | replace ('http:', 'https:') %]' method='post'>
[% ELSE %]
  <form action='[% c.uri_for('/secure/form') %]' method='post'>
[% END %]

Needless to say, this all just seems wrong on multiple levels. Anyone have a better idea? And is there a way to force $c->uri_for to generate a URI that begins with https?

Solution

If you're using Catalyst 5.80008 or later, set MyApp->config(using_frontend_proxy => 1); and simply have your proxy set the X-Forwarded-Port header. For Catalyst versions prior to 5.80008, still set using_frontend_proxy so you get the actual client_ip, but to generate the correct URIs have your web server set the environment variable HTTPS to ON

4

3 に答える 3

12

この構成オプションを試すことができます。

MyApp->config(using_frontend_proxy => 1);

これはCatalystのドキュメントで説明されています

于 2009-11-03T04:07:03.993 に答える
6

次の作品(テスト済み):

MyApp.pmに、次のサブを追加します。

sub secure_uri_for {
    my ($self, @args) = @_;
    my $u = $self->uri_for(@args);
    $u->scheme('https');
    return $u;
}

これで、保証されたhttpsが必要なときはいつでも、電話をかけることができます$c->secure_uri_for('whatever')

于 2009-11-03T03:50:37.100 に答える
1

私はCatalystを使用していませんが、のドキュメントはリクエストオブジェクトのメソッドuri_forを指しています。base

ソースを読んだところ、それbaseが読み取り/書き込み方式であることがわかりました。$req->base('https://foo.bar.com/')したがって、 https urisを取得するために、どこかでコードを圧縮できるはずです。

アップデート:

singingfishは、上記のアドバイスは正しくないと言っています。これは私をまったく驚かせません。TFMをざっと見ただけです。S /彼はまた、scheme代わりにメソッドを設定する必要があると言います。私は彼/彼がuriオブジェクトのschemeメソッドを参照していると思います。

さらに検索すると、CatalystWikiでHTTPSトリックが見つかりましたこれは、メソッドによって返されるuriオブジェクトにスキームを設定する例を示していますuri_for_action。コード全体で、要求するすべてのURIにスキームを設定する必要があるようです。ですから、スキーム方式は最善の選択ではないかもしれないと思わずにはいられません。

このスレッドもメーリングリストで見つけました。base環境変数の設定または設定は、どちらも推奨される方法です。

これにより、いくつかの調査方法が提供されます。幸運を。

于 2009-11-03T02:57:49.373 に答える