为什么$ auth-> loggedIn在我使用CGI :: Session :: Auth :: DBI时永远不会出现?

时间:2010-01-10 23:50:56

标签: perl authentication cgi

使用CGI::Session::Auth::DBICGI::Session::Auth页面中的示例,我尝试实现_login功能但没有成功。我正在使用Windows 7和Apache 2。

#!/usr/bin/perl -w
use strict;

use CGI::Carp qw(fatalsToBrowser);

use CGI;
use CGI::Session;
use CGI::Session::Auth::DBI;

my $cgi = new CGI;

# using '.' directory for testing
my $session = new CGI::Session(undef, $cgi, {Directory=>'.'});
my $auth = new CGI::Session::Auth::DBI({
    CGI => $cgi,
    Session => $session,
    DSN => 'dbi:mysql:dbname=foobar:host=localhost',
    DBUser => 'foo',
    DBPasswd => 'bar',
    UserTable => 'cgi_auth_user' # auth_user already in use
});

print "Content-type: text/html\n\n";

if ($auth->_login("admin", "admin")) {
    print "<p>login ok</p>";
} else {
    print "<p>login fail</p>";
}

if ($auth->loggedIn) {
    print "<p>logged in; go to <a href='index.pl'>index</a></p>";
} else {
    print "<p>not logged in</p>";
}

这个渲染的输出是:

login ok
not logged in

如果我将传递给_login的值更改为“foo”,“bar”(用户名/密码无效),那么我会得到此渲染结果:

login fail
not logged in

我正在使用'。'只是为了测试,因为我知道它是一个我可以写的目录。每次运行代码时,都会创建一个cgisess_文件(例如cgisess_9fb493cc9155ee9dd2b18fddc38139d8),但无论我是否使用正确的用户名,都会创建此文件。没有返回任何错误,但$auth->loggedIn始终为false。

文档说_login是虚拟的,听起来像DBI模块会覆盖它,但我不确定。

我可能做错了什么?

更新1:

我在调用$auth->authenticate()之前也尝试使用$auth->loggedIn,但这没有效果。成功登录后,我也尝试在另一个上使用$auth->authenticate()$auth->loggedIn,但我得到了相同的结果。无论我做什么,$auth->loggedI总是假的。

更新2:

我还尝试将目录转换为“/”,它所做的就是在cgisess而不是当前目录中创建/个文件。

更新3:

我认为这可能是数据库记录的问题;我正在使用示例页面中的默认示例,但使用修改后的管理员密码。这是一个phpMyAdmin导出:

CREATE TABLE IF NOT EXISTS `cgi_auth_user` (
  `userid` char(32) collate utf8_unicode_ci NOT NULL,
  `username` varchar(30) collate utf8_unicode_ci NOT NULL,
  `passwd` varchar(30) collate utf8_unicode_ci NOT NULL default '',
  PRIMARY KEY  (`userid`),
  UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `cgi_auth_user` (`userid`, `username`, `passwd`) VALUES
('325684ec1b028eaf562dd484c5607a65', 'admin', 'admin'),
('ef19a80d627b5c48728d388c11900f3f', 'guest', 'guest');

然后,如果_login使用有效的用户名和密码返回true,那么我会假设用户ID是有效的......不是吗?

更新4:

我也在我们的Linux生产服务器上对此进行了测试,我得到了完全相同的问题。

4 个答案:

答案 0 :(得分:3)

尝试输出$session->header()的结果作为输出的第一件事。这应该设置您的cookie并加载现有会话,而不是每次都创建一个新会话。

此外,_login()仅对数据库执行身份验证,但不会修改$auth对象。使用authenticate(),您需要使用param()对象的$cgi函数定义用户名和密码。您需要为log_username函数设置字段log_passwordauthenticate()才能生效。

#!/usr/bin/perl -w
use strict;

use CGI::Carp qw(fatalsToBrowser);

use CGI;
use CGI::Session;
use CGI::Session::Auth::DBI;

my $cgi = CGI->new;
my $session = new CGI::Session(undef, $cgi, {Directory=>'/tmp'});

my $auth = new CGI::Session::Auth::DBI({
    CGI => $cgi,
    Session => $session,
    DSN => 'dbi:mysql:dbname=foobar:host=localhost',
    DBUser => 'foo',
    DBPasswd => 'bar',
    UserTable => 'cgi_auth_user'
});

print $session->header();

$cgi->param('log_username', 'admin');
$cgi->param('log_password', 'admin');

$auth->authenticate();

if ($auth->loggedIn) {
    print "<p>logged in; go to <a href='index.pl'>index</a></p>";
} else {
    print "<p>not logged in</p>";
}

我还没有测试过,但这应该有效。

答案 1 :(得分:1)

文档非常明确,您必须覆盖_login()方法,除非guest / guest适合您。另外,你没有调用authenticate(),它实际上调用_login(),你不应该这样做。

  

_login()

     

这个虚拟方法执行   通过比较实际登录尝试   访问者发送的登录表单数据   一些本地用户数据库。 _login   基类的方法   CGI :: Session :: Auth只知道用户   “客人”密码为“客人”。

     

要访问真实用户数据库,请执行此操作   必须使用修改的子类   适当的_login方法。看到   Auth /子目录中的模块。

答案 2 :(得分:1)

查看源代码和文档,_login()实际上从未设置内部loggedin标志。这仅在身份验证模块中执行。您还应该记住,通常接受的perl实践是,以“_”开头的方法应该基本上被视为私有方法(或者在Java术语中可能受到保护),仅供子类使用。所以你不应该直接使用_login。

  

LoginVarPrefix:默认情况下,CGI :: Session :: Auth期望访问者的用户名和密码以表单变量'log_username'和'log_password'传递。为避免冲突,可以通过此参数更改前缀“log_”。

我相信这会有用

$session->param('log_username', 'admin');
$session->param('log_password', 'admin');

$auth->authenticate(); # no return value to check

print "Content-type: text/html\n\n";

if ($auth->loggedIn) {
    print "<p>logged in; go to <a href='index.pl'>index</a></p>";
} else {
    print "<p>not logged in</p>";
}

答案 3 :(得分:0)

你可以通过把它放在我的$ cgi = new CGI之上来打开日志记录;线

use Log::Log4perl qw(:easy);
# Set priority of root logger to DEBUG
Log::Log4perl->easy_init($DEBUG);

这将启用调试功能,让您可以查看更多内容。