我使用 Catalyst 编写了一个 Web 应用程序,它有很多表单并且需要通过 https 运行。没有硬编码的 URL,一切都使用$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 开头的 URI?
解决方案
如果您使用的是 Catalyst 5.80008 或更高版本,请设置MyApp->config(using_frontend_proxy => 1);
并让您的代理设置X-Forwarded-Port
标头。对于 5.80008 之前的 Catalyst 版本,仍然进行设置using_frontend_proxy
,以便您获得实际的 client_ip,但要生成正确的 URI,请让您的 Web 服务器将环境变量设置HTTPS
为ON