我差不多两周前就遇到了同样的问题。 我是Perl和Web的新手:/
我按照CGI :: Session教程和Cookbook,代码似乎很好但是......不工作。
的index.cgi
#!/usr/bin/perl
use CGI;
use CGI::Cookie;
use HTML::Template;
use strict;
use warnings;
use CGI::Session;
use CGI::Carp qw(fatalsToBrowser);
require "cgi-bin/web_base.pl";
require "cgi-bin/login.pl";
my $cgi = new CGI;
my $session = new CGI::Session("driver:File", undef, {Directory=>'/tmp'}) or die CGI::Session->errstr;
my $CGISESSID = $session->id();
print header();
print $cgi->header();
print my_topbar();
login_attempt($session, $cgi);
if ( $session->param("~login-trials") >= 3 ) {
print error("You failed 3 times in a row.\n" .
"Your session is blocked. Please contact us with ".
"the details of your action");
exit(0);
}
unless ( $session->param("~logged-in") ) {
print login_form($cgi, $session);
exit(0);
}
print footer();
login.cgi
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use CGI::Cookie;
use HTML::Template;
use CGI::Session;
use CGI::Carp qw(fatalsToBrowser);
use Fcntl;
my $cgi = new CGI;
my $session = new CGI::Session(undef, $cgi, {Directory=>'/tmp'});
sub login_attempt {
my ($session, $cgi) = @_;
if ( $session->param("~logged-in") ) {
return 1; # Verify if user is not logged.
}
my $username = $cgi->param("username") or return;
my $password=$cgi->param("password") or return;
# Form submited. Try to load profile.
if ( my $profile = load_profile($username, $password) ) {
$session->param("~profile", $profile);
$session->param("~logged-in", 1);
print "YOUPIIIII";
$session->clear(["~login-trials"]);
$session->redirect("dashboard.cgi");
return 1;
}
# Failed to login, wrong credentials.
my $trials = $session->param("~login-trials") || 0;
return $session->param("~login-trials", ++$trials);
}
return 1;
sub load_profile {
my ($username, $password) = @_;
local $/ = "\n";
unless (sysopen(PROFILE, "profile.txt", O_RDONLY) ) {
die ("Couldn't open profile.txt: $!");
}
while ( <PROFILE> ) {
/^(\n|#)/ and next;
chomp;
my ($n, $p) = split "\s+";
if ( ($n eq $username) && ($p eq $password) ) {
my $p_mask = "x" . length($p);
return {username=>$n, password=>$p_mask};
}
}
close(PROFILE);
return undef;
}
profile.txt
Formget 123
当我尝试登录时,没有任何事情发生,即使我尝试错误的crendentials它应该在3次尝试后阻止我,但事实并非如此。
有人可以真的帮助我吗?我无法忍受它。
随时提出任何问题:)
编辑:
-login_attempt()更正了
-load-profile不起作用,换了新的,但仍然需要改进。
- 最后问题是会话初始
答案 0 :(得分:2)
您确定没有收到任何错误吗?您是否检查过Web服务器错误日志?
您使用两个参数(login_attempt()
和$session
)调用$cgi
但在login.cgi中,该子例程的定义如下:
sub login_attempt() {
...
}
您(可能是偶然)在该子例程上使用原型,告诉Perl它不需要参数。如果你没有收到错误的话,我会感到惊讶:
main :: login_attempt
的参数太多
从该定义中删除括号。
sub login_attempt {
...
}
更新:我认为你在这里错过了一个非常重要的步骤。来自CGI::Session Tutorial:
在创建CGI :: Session对象之后,应用程序需要执行一个小但非常重要的事情。它需要将会话ID作为HTTP cookie丢弃到用户的计算机中。 CGI :: Session将使用此cookie在他/她的下一个请求中识别用户,并且能够加载他/她以前存储的会话数据。
为了确保CGI :: Session能够在下次请求时读取您的cookie,您需要查询其name()方法以获取cookie的建议名称:
$cookie = $query->cookie( -name => $session->name, -value => $session->id ); print $query->header( -cookie=>$cookie );
name()
默认返回CGISESSID。如果您更喜欢不同的cookie名称,也可以轻松更改它,但必须在创建CGI :: Session对象之前进行更改:CGI::Session->name("SID"); $session = CGI::Session->new();
烘烤饼干并不太难,是吗?但是有一种更简单的方法可以使用CGI :: Session发送cookie:
print $session->header();
以上将使用CGI :: Cookie创建cookie,并使用CGI.pm的CGI方法返回正确的http标头。 CGI :: Session的任何参数都将传递给CGI :: header()。
如果没有这个,您将为每个请求创建一个全新的会话。