Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > Cookie Запись, проверка, выход


Автор: MaxPayne 1.4.2008, 14:37
Для установки куков использую

my $query = CGI->new;
print $query->header(-cookie => $query->cookie(-name => ses, -value => $ses, -expires =>  '+1M'));
---------------------------------------------------------
Для проверки использую

$q = CGI->new();
$vc = $q->cookie('ses');

Если $vc чтото есть - значит кука есть.
-----------------------------------------------------------
Для выхода использую

$q = CGI->new();
$vc = $q->cookie('ses');

$dbh = DBI -> connect("DBI:mysql:***:localhost", "", "");
$dbh -> do("UPDATE user set temp='' WHERE temp = '$vc'");
$dbh -> disconnect();

$q = CGI->new;
$cookie = $q->cookie(-name => ses, -value => $vc, -expires => '-1m');
-----------------------------------------------------------
Все ли правильно здесь описано? Выхода из куков не происходит. Из базы стирается ключ, но сама кука остается. Я писал срок и -1М и now, как где то было уже описано. Но не получается. В чем может быть проблема.

Автор: Itsys 1.4.2008, 16:57
print $query->header(-cookie => $query->cookie(-name => ses, -value => $vc, -expires =>  'now'));

Куки ты создал, а в заголовок кто его будет запихивать?

Автор: MaxPayne 2.4.2008, 11:52
Т.е. для выхода с куков добаляю в конце строку (выделена жирным)

$q = CGI->new();
$vc = $q->cookie('ses');

$dbh = DBI -> connect("DBI:mysql:***:localhost", "", "");
$dbh -> do("UPDATE user set temp='' WHERE temp = '$vc'");
$dbh -> disconnect();

$q = CGI->new;
$cookie = $q->cookie(-name => ses, -value => $vc, -expires => '-1m');
print $query->header(-cookie => $query->cookie(-name => ses, -value => $vc, -expires =>  'now')); 

или 

print $q->header(-cookie => $q->cookie(-name => ses, -value => $vc, -expires =>  'now')); 


Автор: Itsys 2.4.2008, 18:51
ну конечно вторую, это я посто копировал и не посмортел исходную переменную  smile 

Автор: MaxPayne 3.4.2008, 16:47
Спасибо.

Автор: MaxPayne 10.4.2008, 13:49
Блин выход запарил - не выходит. Уже и браузер закрыл, открыл - не помогает.
Может кто подскажет. ПРоблем с входом и проверкой на наличие нет.
ПРивожу код скритп по выходу.

Код

#!/usr/bin/perl
use CGI qw(:all);
use DBI;

$q = CGI->new();
$vc = $q->cookie('ses');

#$dbh = DBI -> connect("DBI:mysql:***:localhost", "", "");
#$dbh -> do("UPDATE user set temp='' WHERE temp = '$vc'");
#$dbh -> disconnect();

print $q->header(-cookie => $q->cookie(-name => ses, -value => $ses, -expires =>  '-1M'));

print "<script language='javascript'> location.href='http://www.***.ru/' </script>";
exit;

Автор: GoDleSS 10.4.2008, 21:23
MaxPayne, редирект проще сделать в том же хидере, зачем жабаскрипт пуляешь?!

Автор: MaxPayne 11.4.2008, 08:53
Поскажите как - сделаю. Но главная проблема что куки не стираются.

Автор: Itsys 12.4.2008, 07:02
Попробуй так:
Код

#!/usr/bin/perl
use CGI qw(:all);
use DBI;

$q = CGI->new();
$vc = $q->cookie('ses');

#$dbh = DBI -> connect("DBI:mysql:***:localhost", "", "");
#$dbh -> do("UPDATE user set temp='' WHERE temp = '$vc'");
#$dbh -> disconnect();
print "Content-type: text/html\n\n";

print $q->header(-cookie => $q->cookie(-name => ses, -value => $ses, -expires =>  '-1M'));

#print "<script language='javascript'> location.href='http://www.***.ru/' </script>";
exit;

и посмотри что он выведет в качестве заголовка

Автор: MaxPayne 12.4.2008, 09:28
Set-Cookie: o2yql0nWos4QwxBPYpsIzul1rmdulR
Date: Sat, 12 Apr 2008 02:30:56 GMT
Content-Type: text/html; charset=ISO-8859-1


В базе MySQL занесена таже сессия: o2yql0nWos4QwxBPYpsIzul1rmdulR
Т.е. все верно.


Аммм. А дата должна выводиться как -1 месяц? Март?

Автор: Itsys 12.4.2008, 10:02
У тебя получается не правильная строка с Куками:
Формат Set-Cookie      
Set-Cookie: name=[значение]; path=[путь]; expires=[дата]; domain=[домен]; secure

Добавлено через 3 минуты и 58 секунд
просто если не указано 
Цитата(Itsys @  12.4.2008,  10:02 Найти цитируемый пост)
expires=[дата]; 

то считается, что куки акивны до тех пор, пока открыто окно браузера.
я, обычно для задания куков пользуюсь модулем CGI::Cookie 

Автор: MaxPayne 12.4.2008, 10:47
Т.е. куки изначально не правильно ставятся?

Автор: Itsys 12.4.2008, 11:01
да

Добавлено через 1 минуту и 23 секунды
посмотри таким же образом что устанавливается при инициализации куков

Автор: MaxPayne 12.4.2008, 16:37
При установке вот так:
Set-Cookie: ses=4vwFiykSzO3BMkXNpMsKKpgKhugdwr; path=/; expires=Mon, 12-May-2008 09:38:47 GMT Date: Sat, 12 Apr 2008 09:38:47 GMT Content-Type: text/html; charset=ISO-8859-1 


Ставлю вот таким образом:
Код

my $query = CGI->new();
print $query->header(-cookie => $query->cookie(-name => ses, -value => $ses, -expires =>  '+1M'));

Автор: Itsys 13.4.2008, 06:37
Значит его глючит на "-1М", попробуй "now"

Автор: MaxPayne 14.4.2008, 20:17
Цитата(Itsys @ 13.4.2008,  07:37)
Значит его глючит на "-1М", попробуй "now"

Если Вы используете use CGI::Cookie; не могли бы привести пример как вы ставите куку, читаете и стираете (стираете я так понял равно ставить с датой now или -ДАТА). 

Автор: Itsys 15.4.2008, 13:50
А http://search.cpan.org/~lds/CGI.pm-3.35/CGI/Cookie.pm читал?

Автор: MaxPayne 15.4.2008, 21:13
Может на форуме после первого вопроса отправлять к документации и закрывать тему? Читал. Выкладывал сюда примеры, читал то что уже писали на этом форуме, тестировал у себя, читал документацию, пробовал другие формы записи куков, опять читал. В итоге запутавшись окончательно  пришел сюда.

Автор: Itsys 15.4.2008, 23:58
MaxPayne, не кипятись, просто если чего не понятно в документации ты скажи, попробуй установить время now, и посмотри что выводит заголовок.

Автор: MaxPayne 17.4.2008, 10:00
Я сделал пробник http://www.3fun.ru/cgi-bin/zzlogin.cgi

Но теперь войти не могу даже. Вилы.

Логин и пароль там test (уже подставлены) 



Ставлю куки как
Код

$c = new CGI::Cookie(-name => 'ses',
             -value => "$ses",
             -expires => '+3M',
             -path => '/'
             -secure => 1
);
print header(-cookie=>$c);
print "<script language='javascript'> location.href='http://www.3fun.ru/cgi-bin/zzlogin.cgi' </script>";


Первая часть такая же как в доках, а вторая часть "print header(-cookie=>$c);"у меня идет так, в доках же написано
Код

$c->bake;

или
Код

print "Set-Cookie: $c\n";
print "Content-Type: text/html\n\n";


Автор: ginnie 17.4.2008, 11:15
MaxPayne, советую внимательно почитать про параметр -secure.

Автор: MaxPayne 17.4.2008, 13:30
ginnie, знаючто для https://. Убрал я его. Но ничего не изменилось


Еще такой момент - принципиально ли для куков какой уровень домена?:

http://www.url.ru/
http://url.ru/

Автор: ginnie 17.4.2008, 13:35
MaxPayne, можно посмотреть код zzlogin.cgi?

Автор: MaxPayne 17.4.2008, 13:52
zzlogin.cgi

Код

#!/usr/bin/perl
use CGI qw(:all);
use CGI::Cookie;
use DBI;

$r=$ENV{'QUERY_STRING_UNESCAPED'};

$q = CGI->new();
$vc = $q->cookie('ses');

$dbh = DBI -> connect("DBI:mysql:3fun:localhost", "", "");
$sth = $dbh->prepare("SELECT * FROM user WHERE temp='$vc'");
$sth->execute;
@ref = $sth->fetchrow_array;
$log=$ref[3];
$sth->finish();
$dbh -> disconnect();



print "Content-Type: text/html\n\n";

if ($log)
{
print qq|
    <td width="100%" ><img width="348" height=1 src="/img/px.gif" usemap="#main">
    <p align=left><b>$log</b><br/><br/>    <a href='/cgi-bin/zzexit.cgi?r=$r'>выход</a>
    |;
}
else
{
    print qq|
    <td id="login_form">
    логин<br/> <form action='/cgi-bin/zzgo.cgi' method="post"><input type="text" id="login" name="l" value="test"> 
    пароль<br/> <input type="password" id="password" name="p" value="test"><INPUT id="lok" 
    TYPE="IMAGE" SRC="/img/ok.jpg" ALT="Submit button"></form>
    $vc, $log
     <a href="/cgi-bin/reg.cgi?r=$r">регистрация</a><br/><a href="/cgi-bin/recover.cgi?r=$r">забыли пароль?</a>
    |;
}

exit;

Автор: ginnie 17.4.2008, 14:08
MaxPayne, домен принципиален. Чтобы работало на всех, надо указывать '.url.ru'.

При заходе на тестовую страницу (http://www.3fun.ru/cgi-bin/zzlogin.cgi) у меня выдает Max Payne и выход  smile 

Автор: MaxPayne 17.4.2008, 14:23
Т.е надо писать не
-path => '/'
а
-path => '.url.ru'


А выйти вы можете? 

Автор: ginnie 17.4.2008, 14:36
MaxPayne, для домена отдельный параметр 

Код

-domain  =>  '.url.ru',



Выйти не могу. Посмотрел что происходит при взаимодействии с Вашими скриптами.

При нажатии на выход zzexit.cgi ставит cookie 'ses' с пустым значением и путем '.3fun.ru' (это, наверное, Вы экспериментируете). Время устаревания 'Thu, 17-Apr-2008 07:37:14 GMT' (это в 15:35 MSK). Заголовки смотрю при помощи плагина HttpWatch для IE.

Автор: MaxPayne 21.4.2008, 09:42
ginnie, 
НУ поидее выход это установка куков с датой устаревания now. Т.е. поидее это нормально то что он ставит такую куку.

Плагин HttpWatch нашел, но он платный.

Автор: shamber 21.4.2008, 09:50
MaxPayne, поставте proxomitron он как прокси работает, бесплатный и можно просматривать запросы.

Автор: MaxPayne 22.4.2008, 15:41
ginnie, Странно что ставит пустую, ведь из базы нужная кука удаляется.

zzexit.cgi

Код

#!/usr/bin/perl
use CGI qw(:all);
use CGI::Cookie;
use DBI;

$q = CGI->new();
$vc = $q->cookie('ses');

$dbh = DBI -> connect("DBI:mysql:3fun:localhost", "***", "***");
$dbh -> do("UPDATE user set temp=\"\" WHERE temp = \"$vc\"");
$dbh -> disconnect();

$c = new CGI::Cookie(-name => 'ses',
             -value => "$vc",
             -expires => 'now',
             -path => '/',
             -domain  =>  '.3fun.ru',
);
print header(-cookie=>$c);

print "<script language='javascript'> location.href='http://www.3fun.ru/cgi-bin/zzlogin.cgi' </script>";
exit;


Может есть фишка еще в кавычках? В раличном написании: ' или ".

Автор: tolkien 22.4.2008, 17:19
Протокол работ кук очень простой. Реализуйте свой модуль.

Автор: KSURi 22.4.2008, 18:45
Цитата(tolkien @ 22.4.2008,  17:19)
Протокол работ кук очень простой. Реализуйте свой модуль.

IMHO не хороший совет. Зачем человеку изобретать очередной велосипед (даже не "велосипед", а "велосипедище")?
Нужно просто получше почитать документацию по CGI::Cookie и RFC 2965.

У меня работает вот такой код (кука нормально удаляется, FF2.0.14):
Код

#...
# LogIn
return CGI->cookie(-name    => 'CGISESSID',
                -value   => $session_key,
                -expires => '+1h');
#...
# LogOut
return CGI->cookie(-name    => 'CGISESSID',
                -value   => '',
                -expires => 'now');
#...
exit print $cgi->header(-charset  => 'windows-1251',
                        -cookie   => $res,
                        -location => 'http://' . $ENV{SERVER_NAME} . ($isLoggedIn ? $success_redirect : $failure_redirect))


Автор: MaxPayne 22.4.2008, 21:47
tolkien, 
Научи меня летать учитель - летать очень легко сказал учитель и улетел

KSURi, 
Все просто когда уже работал с этим. Дело в том что с куками возился год назад, но как и щас чтото получилось чтото нет. Когда в сумме все не работает, "организм" в целом мертв.
Документацию читал, но опять же может не все понимаю по английски - что не понятно уже писал на прошлой странице. Вопрос в принципе в следующем - почему не работает ВЫХОД. Пример тоже на прошлой странице. 

То что вариантов реализаций много я понял - и это как раз и сбивает.


Автор: KSURi 22.4.2008, 22:04
MaxPayne, зашел на ваш линк (http://www.3fun.ru/cgi-bin/zzlogin.cgi). При входе куки не устанавливаются, при нажатии на "Выход" (кстати параметр r для zzexit.cgi пуст, так и должно быть?) устанавливается пустая кука ses (ну т.е. в запросе ее установку видно, но в браузере она не сохраняется).

Я не совсем понял где все-таки баг... В любом случае попробуйте использовать код для установки кук, который я привел выше.

ЗЫ: в вашем случае редирект имхо лучше будет сделать через <meta name="refresh">

Автор: MaxPayne 24.4.2008, 12:10
KSURi, Меня смущает return. Что мне нужно поставить вместо:?

Код

$c = new CGI::Cookie(-name => 'ses',
             -value => "$ses",
             -expires => '+3M',
             -path => '/',
             -domain  =>  '.3fun.ru',
 
);
print header(-cookie=>$c);

Автор: KSURi 24.4.2008, 13:08
У меня стоит return потому, что куки возвращают несколько ф-ий, соответственно это просто отрывоки из них. Привел я их для того, чтобы показать, что необязательно указывать параметры -path, -domain и т.д.

Автор: MaxPayne 28.4.2008, 12:40
KSURi, домен я поставил для того чтобы и www.3fun.ru и 3fun.ru восринимались как один для кук.

Вроде заработало
Если будет возможность проверьте у себя: http://www.3fun.ru/cgi-bin/zzlogin.cgi
Логин и пароль test (уже подставлены)

Проблемы были 2:
1) Если куки были пустые в базе все равно находились записи с пустым полем и выдавало первую попавшуюся
2) По всей видимости надо было писать переменную не в кавычках: -value => "$ses"

Если все работает могу дать кодинг трех файлов (вход, выход и форма)

Автор: shamber 28.4.2008, 18:01
MaxPayne, потестировал. На этой странице ничего не происходит. т.е. 
было такое окно
user posted image

после нажатия OK, тоже самое.
Так и должно быть?
З.Ы. В опере тестировал

Автор: MaxPayne 28.4.2008, 22:33
shamber, дома перестало все работать. Не могу зайти. Так же не должно быть  smile 

Как завелась кука на компе, так больше не могу войти - новая кука не накладывается одна на другую при новом входе.

Автор: shamber 29.4.2008, 08:46
Видимо у меня тоже есть старая кука.
Я его тестировал когда Вы только доступ предложили smile

Автор: MaxPayne 29.4.2008, 14:19
shamber, Блин на работе все ок (Vista SP1 + IE 7)

Должно быть вот это:

user posted image

Автор: shamber 30.4.2008, 08:15
user posted image

Это в опере. Просто я с ее помощью заходил на Ваш сайт, когда скрипт не совсем корректно работал.

А В IE6 все нормально, т.к. я его не использовал раньше для вашего сайта. smile

P.S. ИМХО можно не заморачиваться, я думаю людей со старыми куками не так много smile

Автор: Itsys 30.4.2008, 09:38
Цитата(shamber @  30.4.2008,  08:15 Найти цитируемый пост)
P.S. ИМХО можно не заморачиваться, я думаю людей со старыми куками не так много 

Не скажи, а если пользователь не нажмет кнопку "Выйти", а запись о его сессии с сервера удалится и при следующем заходе опять будет такая же ситуация.... я с такими случаями уже сталкивался.
Надо при получении куки от пользователя проверять наличие в базе соответсвующей записи, и, в случае, если ее нет, перезаписывать куки на новые.

Автор: shamber 30.4.2008, 10:06
Itsys, я имел в виду конкретно этот пример. smile 
А то что надо перезаписывать это правильно.
MaxPayne, вы же уже разобрались с перезаписью?

Автор: MaxPayne 1.5.2008, 23:13
shamber, не совсем. Как и на приведенном вами рисунке - Записанная кука есть, но в базе ее нет, поэтому выводит форму. Но когда жму войти проверяется логин и пароль, в базу заносится новая кука и записывается на комп. Но в тот то и дело что кука не перезаписывается - т.е. не накладывается поверх.

Автор: Vavilen 12.7.2009, 21:21
Здравствуйте!
Проблема такова:
не могу передать куку броузеру
вот кусок модуля:
Код

sub render_page {
    my $self = shift;
    my ($tmpl_file, $params) = @_;
    my $cookie =$self->_cookie();
    
    $tmpl_file || die "Expected tmpl file!";
    my $tmpl = HTML::Template -> new (filename => $tmpl_file, die_on_bad_params => 0);
    $tmpl -> param (EMPLOYEE_INFO => $params) if ref $params eq 'ARRAY';
    $tmpl -> param($params) if ref $params eq 'HASH';
       print "Content-Type: text/html\n\n";
       print "Set-Cookie: $cookie\n";
    print $tmpl->output;
}

При этом кука выводится на экран в броузее, а не передается в заголовке smile
пробовал по аналогии с документации CGI::Cookie, то есть:
If you want to set the cookie yourself, Within a CGI script you can send a cookie to the browser by creating one or more Set-Cookie: fields in the HTTP header. Here is a typical sequence:
Код

my $c = new CGI::Cookie(-name    =>  'foo',
                          -value   =>  ['bar','baz'],
                          -expires =>  '+3M');

  print "Set-Cookie: $c\n";
  print "Content-Type: text/html\n\n";

В этом случае кука вообще никак не передается.
Подскажите, пожалуйста, в чем проблема?

Автор: KSURi 13.7.2009, 15:05
Код

       print "Content-Type: text/html\n\n";
       print "Set-Cookie: $cookie\n";

Найдите отличие своего кода от примера CGI::Cookie. Вы отделили заголовки от контента слишком рано.

ЗЫ: кстати, насколько я помню, по RFC правильно делать "\r\n" x 2, а не "\n\n"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)