$c->res->redirect('/foo');
对于大多数现代浏览器,这个响应返回的头部是可以被正常解析的,所以如果你是从一个https入口进的话,这个重定向会正确地被浏览器解析成
https://example.com/foo
但是,根据RFC某某某号的描述,重定向的目标路径应该是全路径,这样的话就有问题了,首先,你必须借助uri_for这个函数来产生你的全路径
$c->res->redirect( $c->uri_for('/foo') )
然后,问题就来了,由于Catalyst只接受到了http的请求,它并不知道外面的世界是上海还是广州,于是,得到了
http://example.com/foo
诚然,也许你要的只是某个区域永远安全,那么简单的解决方法就是这样
my $uri = 'https://' . $c->req->header('host') . '/foo';
$c->res->redirect( $uri );
显然,我们要得更多,又要马儿好,又要马儿不吃草。所以呢,在很多站点的入口都能看到一个醒目的“安全登录”的标签。让你自己选,要安全就给你安全,不要?呵呵,我乐得省下这些开销。这样的话,情况就要复杂一些了,首先,为了让Catalyst知道你的来路,Pound必须履行告知的义务,比如这样
ListenHTTPS
AddHeader "secure: 1"
End
接着,就可以根据这个头部来分情况选择重定向的协议(schema)了,我比较倾向于自己写个插件
package Catalyst::Plugin::Secure;
use strict;
use warnings;
sub uri_for {
my ( $c, $path, @args ) = @_;
my $uri = $c->NEXT::uri_for($path, @args);
if ( $c->req->header('secure') ) {
my $str = $uri->as_string;
$str =~ s/^http/https/;
$uri = new URI( $str )->canonical;
}
return $uri;
}
1;
好,圆满了,多谢观赏!
No comments:
Post a Comment