有没有办法强制在Catalyst中使用$ c-> uri_for来生成以https开头的URI?

时间:2009-11-03 02:10:12

标签: perl catalyst

我使用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?

开头的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

3 个答案:

答案 0 :(得分:12)

您可以尝试以下配置选项:

MyApp->config(using_frontend_proxy => 1);

Catalyst's documentation

中有描述

答案 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或设置环境变量都是推荐的方法。

这为您提供了几种调查途径。祝你好运。