为什么在我使用 CGI::Session::Auth::DBI 时 $auth->loggedIn 从来都不是 true?
使用 CGI::Session:: 中的示例Auth::DBI 和 CGI::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->loggedIn
之前使用 $auth->authenticate()
但这没有效果。我还尝试在成功登录后在另一个上使用 $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 生产服务器上对此进行了测试,并且遇到了完全相同的问题。
Using the examples from the CGI::Session::Auth::DBI and CGI::Session::Auth pages, I have attempted to implement the _login
function with no success. I'm using Windows 7 and 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>";
}
The rendered output from this is:
login ok
not logged in
If I change the values passed to _login
to "foo", "bar" (an invalid username/password), then I get this rendered result:
login fail
not logged in
I'm using '.' just for testing as I know it's a dir I can write to. Every time I run the code, a cgisess_
file is created (e.g. cgisess_9fb493cc9155ee9dd2b18fddc38139d8
), but this is created regardless of if I use a correct username or not. No errors are being returned, but $auth->loggedIn
is always false.
The documentation says that _login
is virtual, and it sounds like the DBI module overrides this, but I'm not sure.
What could I be doing wrong?
Update 1:
I've also tried using $auth->authenticate()
before the call to $auth->loggedIn
but this has no effect. I've also tried using $auth->authenticate()
and $auth->loggedIn
on another after successful login, but I get the same result. No matter what I do, $auth->loggedI
is always false.
Update 2:
I've also tried chaning the directory to "/" and all it does is create the cgisess
files in /
rather than current dir.
Update 3:
I figured it may be an issue with the database records; I'm using the default example ones from the example page, but with a modified admin password. Here's a phpMyAdmin export:
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');
Then again, if _login
is returning true
with a valid username and password, then I would assume that the userid is valid... No?
Update 4:
I've also tested this on our Linux production server, and I get the exact same issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试输出
$session->header()
的结果作为您输出的第一件事。这应该设置您的 cookie 并加载现有会话,而不是每次都创建一个新会话。另外,
_login()
仅执行与数据库的身份验证,但不会修改$auth
对象。使用authenticate()
时,您需要使用$cgi
对象的param()
函数定义用户名和密码。您需要设置字段log_username
和log_password
才能使authenticate()
函数正常工作。我还没有测试过,但这应该有效。
Try outputting the results of
$session->header()
as the first thing you output. This should set your cookie and load the existing session instead of creating a new one each time.Also,
_login()
only performs the authentication with the database, but does not modify the$auth
object. Usingauthenticate()
, you need to define the username and password using theparam()
function of your$cgi
object. You need to set the fieldslog_username
andlog_password
for theauthenticate()
function to work.I haven't tested it, but this should be working.
该文档非常清楚,您必须重写 _login() 方法,除非 guest/guest 适合您。另外,您没有调用authenticate(),它实际上调用了_login(),您不应该这样做。
The doc is pretty clear that you have to override the _login() method, unless guest/guest works for you. Plus you aren't calling authenticate(), which actually invokes _login(), you shouldn't be doing it.
查看源代码和文档,
_login()
实际上从未设置内部loggedin
标志。这仅在身份验证模块中执行。您还应该记住,普遍接受的 Perl 实践是以“_”开头的方法本质上应该被视为私有方法(或者在 Java 术语中可能是受保护的),仅供子类使用。所以你不应该直接使用 _login 。我相信这会起作用
Looking at the source code and documentation,
_login()
never actually sets the internalloggedin
flag. That is only performed in the authenticate module. You should also remember that it is generally accepted perl practice that methods starting with '_' should be treated essentially as private methods, (or in Java terminology perhaps protected) only to be used by subclasses. So you shouldn't be using _login directly.I believe this will work
您可以通过将其放在 my $cgi = new CGI; 之上来打开日志记录这
将打开调试并让您了解更多正在发生的事情。
You can turn on logging by putting this above the my $cgi = new CGI; line
This will turn on debugging and allow you to see more of what is going on.