Почему $auth-> loggedIn никогда не верный в моем использовании CGI:: Сессия:: Автор:: DBI?

Используя примеры от CGI:: Сессия:: Автор:: DBI и CGI:: Сессия:: Подлинные страницы, я попытался реализовать _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 "

login ok

"; } else { print "

login fail

"; } if ($auth->loggedIn) { print "

logged in; go to index

"; } else { print "

not logged in

"; }

Представленный вывод от этого:

login ok
not logged in

Если я изменяюсь, значения передали _login к "нечто", "панель" (неверное имя пользователя / пароль), затем я получаю этот представленный результат:

login fail
not logged in

Я использую '.' только для тестирования, поскольку я знаю, что это - dir, в который я могу записать. Каждый раз я выполняю код, a cgisess_ файл создается (например. cgisess_9fb493cc9155ee9dd2b18fddc38139d8), но это создается независимо от того, если я использую корректное имя пользователя или нет. Никакие ошибки не возвращаются, но $auth->loggedIn всегда ложь.

В документации говорится это _login является виртуальным, и это кажется, что модуль DBI переопределяет это, но я не уверен.

Что я мог делать неправильно?

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

Я также попытался использовать $auth->authenticate() перед вызовом к $auth->loggedIn но это не имеет никакого эффекта. Я также попытался использовать $auth->authenticate() и $auth->loggedIn на другом после успешного входа в систему, но я получаю тот же результат. Независимо от того, что я делаю, $auth->loggedI всегда ложь.

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

Я также попробовал chaning каталог к "/" и все, что он делает, создают cgisess файлы в / вместо текущего dir.

Обновление 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, и я получаю ту же самую проблему.

7
задан Nick Bolton 11 January 2010 в 17:05
поделиться

4 ответа

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

также _Login () выполняет только аутентификацию с базой данных, но не модифицирует объект $ auth объект. Использование аутентификация () , вам необходимо определить имя пользователя и пароль, используя функцию функции вашего $ CGI объекта. Вам необходимо установить поля log_username и log_Password для функции функции () для работы.

#!/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>";
}

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

3
ответ дан 7 December 2019 в 12:20
поделиться

Док довольно ясно, что вы должны переопределить метод _Login (), если гость / гостевой не работает для вас. Кроме того, вы не звоните в аутентификацию (), что на самом деле вызывает _login (), вы не должны его делать.

_Login ()

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

Чтобы получить доступ к реальной базе данных пользователей, вы должны использовать подкласс, который модифицирует метод _Login соответственно. Видеть Модули в auth / subdirectory.

1
ответ дан 7 December 2019 в 12:20
поделиться

Глядя на исходный код и документацию, _Login () никогда не устанавливает внутренний флаг . Это выполняется только в аутентифицированном модуле. Вы также должны помнить, что обычно принимается практика Perl, что методы, начинающиеся с «_», следует обрабатывать по существу, как частные методы, (или в терминологии Java, возможно, защищены только для использования подклассов. Таким образом, вы не должны использовать _Login напрямую.

LoginVArPrefix: по умолчанию CGI :: SEASES :: 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
ответ дан 7 December 2019 в 12:20
поделиться

Целью виртуального деструктора (т.е. целью создания деструктора виртуального ) является облегчение полиморфного удаления объектов посредством delete-выражения . Если конструкция не требует полиморфного удаления объектов, виртуальные деструкторы не нужны. Ссылаясь на пример, если когда-либо потребуется удалить объект типа B через указатель типа A * (полиморфное удаление), в иерархии потребуется виртуальный деструктор высотой A . Так выглядит с формальной точки зрения.

(Примечание, BTW, как сказал Нил, важно то, как вы создаете/удаляете объекты класса, а не как классы управляют своей внутренней памятью.)

Что касается хороших практик программирования... Это зависит от вашего намерения и вашего дизайна в конечном итоге. Если ваши классы вообще не разработаны как полиморфные (виртуальные методы отсутствуют), то вам не нужны виртуальные деструкторы. Если ваш класс является полиморфным (иметь хотя бы один виртуальный метод), то сделать деструктор виртуальным «на всякий случай» может быть очень хорошей идеей, и в этом случае он несет практически нулевое снижение производительности/памяти с ним.

Последнее обычно выражается как довольно хорошо известное практическое руководство: если ваш класс имеет хотя бы один виртуальный метод, сделайте деструктор также виртуальным. Хотя с формальной точки зрения виртуальный деструктор там может и не понадобиться, это все еще довольно хорошее руководство.

Классы, которые не имеют ресурсов, но могут формировать полиморфные иерархии, должны всегда определять пустые виртуальные деструкторы, за исключением того, что совершенно достаточно определить явный пустой (и даже чистый) виртуальный деструктор в самом основании иерархии. Все остальные деструкторы становятся виртуальными автоматически, даже если они определены компилятором неявно. Т.е. нет необходимости явно определять пустой деструктор в каждом классе. Просто базы достаточно.

-121--2126625-

Дополнение к приведенному выше ответу. В итоге я получил это как мою реализацию InvalidInputException:

@WebFault(faultBean = "com.mypackage.ws.exception.FaultBean")
public class InvalidInputException extends Exception {

    private static final long serialVersionUID = 1L;

    private FaultBean faultBean;

    public InvalidInputException() {
        super();
    }

    public InvalidInputException(String message, FaultBean faultBean, Throwable cause) {
        super(message, cause);
        this.faultBean = faultBean;
    }

    public InvalidInputException(String message, FaultBean faultBean) {
        super(message);
        this.faultBean = faultBean;
    }

    public FaultBean getFaultInfo() {
        return faultBean;
    }
}

И FureBean является просто POJO с в настоящее время вообще нет данных. Теперь, в соответствии со спецификацией JAX-WS (см. 3.7 Исключение для конкретной службы), оно соответствует тому, что требуется для исключения, аннотированного с помощью @ WebFault, поэтому оно не создаст компонент-обертку для него, что, вероятно, было неудачным.

Это достойный обходной путь, но он не объясняет ошибку в вопросе.

-121--1419989-

Вы можете включить ведение журнала, поставив это выше моего $ cgi = новый CGI; Строка

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

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

0
ответ дан 7 December 2019 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: