我正在编写一个需要使用模块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?
答案 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 );
}