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

Nic*_*ton 7 authentication perl 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>";
}
Run Code Online (Sandbox Code Playgroud)

这个渲染的输出是:

login ok
not logged in
Run Code Online (Sandbox Code Playgroud)

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

login fail
not logged in
Run Code Online (Sandbox Code Playgroud)

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

文档说这_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');
Run Code Online (Sandbox Code Playgroud)

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

更新4:

我也在我们的Linux生产服务器上测试了这个,我得到了完全相同的问题.

Wol*_*olf 4

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

并且,_login()仅与数据库进行验证,但不修改$auth对象。使用 时authenticate(),您需要使用param()对象的函数定义用户名和密码$cgi。您需要设置字段log_usernamelog_password才能使该authenticate()功能发挥作用。

#!/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>";
}
Run Code Online (Sandbox Code Playgroud)

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