Perl,CGI :: Session无法正常工作

时间:2010-12-09 02:10:31

标签: perl cgi

我正在编写一个需要使用模块CGI::Session ver 4.35的Web应用程序。在收到来自客户端的请求后,使用SESSIONID字符串

$sid = $cgi->cookie("CGISESSID") || $cgi->param("CGISESSID") || undef;

它尝试通过将$ sid作为参数传递来重新创建会话

$session = new CGI::Session($sid) or ($logger->error(CGI::Session->errstr) and die);

如果使用该sid创建了会话,$session->id$sid 假设是相同的,但事实是

这是我创建一个全新会话的声明

$session = new CGI::Session("id:md5", undef, {Directory=>$SESSION_DIR}) 
    or ($logger->error(CGI::Session->errstr) and die);

这里出了什么问题?我该如何正确使用模块CGI :: Session?

3 个答案:

答案 0 :(得分:5)

我是CGI :: Session的维护者。我建议在所有情况下以相同的方式创建会话,如下所示:

$session = CGI::Session->new("id:md5", $cgi, {Directory=>$SESSION_DIR});

这遵循new()文档中的推荐语法。我还建议您确保在脚本末尾附近显式调用flush()。其原因在这里解释得更多:

http://metacpan.org/pod/CGI::Session#A-Warning-about-Auto-flushing

答案 1 :(得分:2)

你真的没有必要自己抓住会话cookie。如果您将CGI对象实例传递给CGI :: Session,它会为您完成。所以,基本上,jfd的上述代码可以像这样重写:

my $session = CGI::Session->new( $query );
$self->header_props(-cookie => $session->cookie);

$query->cookie()if/else块都是多余的,因为它们已经存在于CGI :: Session的逻辑中了!

因此,上面的代码会检查名为CGI::Session->name的客户端cookie(默认为CGISESSID)。如果它不存在,则在URL或请求的CGI::Session->name(也默认为CGISESSID)中查找查询参数。如果它可以获得声明的会话ID,它会尝试将其数据加载到会话中。如果无法验证会话ID(过期或伪造),则会忽略它,并创建一个全新的空会话。

如果在cookie或URL参数中都找不到会话ID,则会创建一个新会话。

我发现会话管理的大多数例子都试图在使用CGI :: Session时重新发明代码中的会话逻辑。我在这里告诉你,所有代码都是完全冗余的!

享受使用CGI :: Session!

答案 2 :(得分:0)

所以,我不清楚你为什么两次创建会话?您想首先尝试获取sid,然后使用它创建会话,无论它是否存在。如果它不存在,请设置cookie。已经有一段时间了,但我从一段旧代码中提取了这个......

my $sid = $query->cookie('CGISESSID') || undef;
# grab the session obj, if one already exists otherwise create one
my $session = new CGI::Session( "id:md5", $sid, { Directory => $SESSION_DIR } );
# If there is no user cookie, or it's non existent, we give them a new one
if ( !$sid or $sid ne $session->id ) {
    my $cookie = $query->cookie(
        -name    => 'CGISESSID',
        -value   => $session->id,
        -expires => EXPIRE_TIME
    );
    $self->header_props( -cookie => $cookie );
}
相关问题