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?
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.
I've also tried chaning the directory to "/" and all it does is create the cgisess
files in /
rather than current dir.
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?
I've also tested this on our Linux production server, and I get the exact same issue.
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()
This virtual method performs the actual login attempt by comparing the login form data the visitor sent with some local user database. The _login method of the base class CGI::Session::Auth only knows the user 'guest' with password 'guest'.
To access a real user database, you have to use a subclass that modifies the _login method appropriately. See the modules in the Auth/ subdirectory.
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. Using authenticate()
, you need to define the username and password using the param()
function of your $cgi
object. You need to set the fields log_username
and log_password
for the authenticate()
function to work.
#!/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>";
}
I haven't tested it, but this should be working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With