我使用Catalyst编写了一个Web应用程序,它有很多表单,需要在https上运行。没有硬编码的网址,所有网址都使用$c->uri_for
或$c->req->uri
。使用运行在http。
今天,当我继续部署应用程序时,我发现了一个问题。我们的生产环境目前的设置方式是,客户端浏览器通过HTTPS与F5负载均衡器通信,F5通过HTTP与内部网络上的Web服务器通信。
[浏览器] --- HTTPS ---> [F5] --- HTTP ---> [Web服务器]
现在,因为Web服务器只获得HTTP
个请求,所以所有URI都是从HTTP开始生成的。这意味着:
<form action='[% c.uri_for('/secure/form') %]' method='post'>
变为:
<form action='http://websitename.org/secure/form' method='post'>
现在所有浏览器都抱怨您通过不安全的连接提交数据。我需要c.uri_for
以https开头。
该应用程序需要今天上线,因此我对所有表单操作进行了大规模搜索/替换:
<form action='[% c.uri_for('/secure/form') | replace('http:', 'https:'%]' method='post'>
好吧,现在打破了开发,所以我基于配置键来限制表单操作:
[% 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 %]
毋庸置疑,这在多个层面上看起来都是错误的。谁有更好的主意?有没有办法强制$c->uri_for
生成以https?
如果您使用的是Catalyst 5.80008或更高版本,请设置MyApp->config(using_frontend_proxy => 1);
,然后让代理设置X-Forwarded-Port
标头。对于5.80008之前的Catalyst版本,仍然设置using_frontend_proxy
以获得实际的client_ip,但要生成正确的URI,您的Web服务器将环境变量HTTPS
设置为ON
答案 0 :(得分:12)
答案 1 :(得分:5)
以下作品(已测试):
在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')
答案 2 :(得分:1)
我不使用Catalyst,但uri_for
的文档指向the request object's base
method。
我阅读了源代码,发现base
是一种读/写方法。因此,您应该可以将$req->base('https://foo.bar.com/')
压缩到代码中以获取您的https uris。
更新:
singfish 表示上述建议不正确 - 这根本不会让我感到惊讶,它基于对TFM的快速审视。他/她还说应该设置scheme
方法。我假设他/她指的是 uri 对象的scheme
方法。
进一步搜索HTTPS Tricks on the Catalyst Wiki。它显示了在uri_for_action
方法返回的 uri 对象上设置方案的示例。您似乎需要在您的请求的每个uri上设置方案,遍布您的代码。所以,我不禁觉得方案方法可能不是最好的选择。
我还找到了this thread on the mailing list。设置base
或设置环境变量都是推荐的方法。
这为您提供了几种调查途径。祝你好运。