Используя примеры от 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 переопределяет это, но я не уверен.
Что я мог делать неправильно?
Я также попытался использовать $auth->authenticate()
перед вызовом к $auth->loggedIn
но это не имеет никакого эффекта. Я также попытался использовать $auth->authenticate()
и $auth->loggedIn
на другом после успешного входа в систему, но я получаю тот же результат. Независимо от того, что я делаю, $auth->loggedI
всегда ложь.
Я также попробовал chaning каталог к "/" и все, что он делает, создают cgisess
файлы в /
вместо текущего dir.
Я полагал, что это может быть проблема с записями базы данных; я использую в качестве примера по умолчанию от страницы в качестве примера, но с измененным паролем администратора. Вот экспорт 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
с допустимым именем пользователя и паролем, затем я предположил бы, что идентификатор пользователя допустим... Нет?
Я также протестировал это на нашем рабочем сервере Linux, и я получаю ту же самую проблему.
Попробуйте выводить результаты $ 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>";
}
Я не проверил его, но это должно работать.
Док довольно ясно, что вы должны переопределить метод _Login (), если гость / гостевой не работает для вас. Кроме того, вы не звоните в аутентификацию (), что на самом деле вызывает _login (), вы не должны его делать.
_Login ()
Этот виртуальный метод выполняет фактическая попытка входа в систему, сравнивая данные для входа в систему Данные посетитель отправлен Некоторая локальная пользовательская база данных. _Login. Метод базового класса CGI :: Сессия :: Auth знает только пользователя «Гость» с паролем «Гость».
Чтобы получить доступ к реальной базе данных пользователей, вы должны использовать подкласс, который модифицирует метод _Login соответственно. Видеть Модули в auth / subdirectory.
Глядя на исходный код и документацию, _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>";
}
Целью виртуального деструктора (т.е. целью создания деструктора виртуального ) является облегчение полиморфного удаления объектов посредством 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);
Это включит отладку и позволит вам увидеть больше того, что происходит.