Why is $auth->loggedIn never true in my use of CGI::Session::Auth::DBI?
authentication, cgi, perl
Solution
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.
Problem
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.