Почему $ auth-> loggedIn никогда не верен в моем использовании CGI :: Session :: Auth :: DBI? - PullRequest
7 голосов
/ 11 января 2010

Используя примеры из страниц 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 всегда ложно.

В документации сказано, что _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 с действительным именем пользователя и паролем, то я бы предположил, что идентификатор пользователя действителен ... Нет?

Обновление 4:

Я также проверил это на нашем производственном сервере Linux, и у меня точно такая же проблема.

Ответы [ 4 ]

3 голосов
/ 22 января 2010

Попробуйте вывести результаты $session->header() как первое, что вы выводите. Это должно установить ваш файл cookie и загрузить существующий сеанс вместо того, чтобы каждый раз создавать новый.

Кроме того, _login() только выполняет аутентификацию с базой данных, но не изменяет объект $auth. Используя authenticate(), вам нужно определить имя пользователя и пароль, используя функцию param() вашего объекта $cgi. Вам нужно установить поля log_username и log_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>";
}

Я не проверял это, но это должно работать.

1 голос
/ 14 января 2010

Глядя на исходный код и документацию, _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>";
}
1 голос
/ 11 января 2010

В документе достаточно ясно, что вы должны переопределить метод _login (), если только гость / гость не работает для вас. Кроме того, вы не вызываете authenticate (), который на самом деле вызывает _login (), вы не должны этого делать.

_login ()

Этот виртуальный метод выполняет фактическая попытка входа в систему путем сравнения данные формы входа, отправленные посетителем некоторая локальная база данных пользователей. _Login метод базового класса CGI :: Session :: Auth знает только пользователь «гость» с паролем «гость».

Для доступа к реальной пользовательской базе данных вы должны использовать подкласс, который изменяет метод _login соответственно. Увидеть модули в подкаталоге Auth /.

0 голосов
/ 14 января 2010

Вы можете включить ведение журнала, поставив его выше my CGI = new CGI; линия

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

Это включит отладку и позволит вам увидеть больше происходящего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...