Forum Webscript.Ru

Программирование => Perl => Тема начата: Inecs от 08 Июля 2005, 17:47:28

Название: Конкретная задача. Сессии на Perl.
Отправлено: Inecs от 08 Июля 2005, 17:47:28
Господа, возник вот какой вопрос. Есть таблица (БД - MySql).
Структура её такова:
id (пользователя), name (‘имя пользователя’), pass (‘пароль’).
Как организовать аутентификацию пользователя с помощью CGI::Session. Желательно использую БД, а не файлы.
Если можно, то конкретный пример. За ранее спасибо.
Название: Конкретная задача. Сессии на Perl.
Отправлено: AnnA от 08 Июля 2005, 18:07:29
Цитировать
Inecs:
Есть таблица

имеется ввиду mysql.user? :)
ох, сейчас начнут вас отправлять в CGI::Session::Tutorial  и CGI::Session::CookBook. в лучшем случае. :)
Вот как в "разжеванной документации" (тут на форуме мне как-то написали, что мол в перлдок все расписано очень подробненько и нечего на форумах вопросы задавать):
To store session data in MySQL database, you first need to create a suitable table for it with the following command:
    CREATE TABLE sessions (
        id CHAR(32) NOT NULL UNIQUE,
        a_session TEXT NOT NULL
    );
You can also add any number of additional columns to the table, but the above "id\'\' and "a_session\'\' are required.

На этих подробностях я пока отложила решение вопроса авторизации. Но идея была таковой:
некто вводит в форму свои логин/пароль, соединяется с базой,
сохраняем сессию на диск и прописываем в таблицу sessions ИД пользователя и номер его сессии, а по ссылкам потом таскаем этот номер сессии или в кваери_стринг или в инпут тайп=хидден.
только не очень понятен механизм, удаления сессии, если например, пользователь поменял пароль. или вообще, что-либо поменял, при очередном входе.
интересный вы вопрос подняли. :)
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 08 Июля 2005, 19:11:28
Цитировать
Inecs:
id (пользователя), name (‘имя пользователя’), pass (‘пароль’). Как организовать аутентификацию пользователя с помощью CGI::Session. Желательно использую БД, а не файлы.

отдельно использовать таблицу с данными CGI::Session.
После проверки сесии получаешь id пользователя (+любые другие данные сесии) и соответственно вытягиваешь все из своей БД.
Не стоит одно с другим накрепко связывать.

Цитировать
AnnA:
ох, сейчас начнут вас отправлять в CGI::Session::Tutorial и CGI::Session::CookBook.

именно так :) там все расписано.
Название: Конкретная задача. Сессии на Perl.
Отправлено: AnnA от 11 Июля 2005, 12:56:22
Green Kakadu да нет там нифига. :) извините.
я говорю именно про алгоритм - реализация не нужна: справлюсь.
Распишите пож-ста, если не сложно.
как я уже говорила - вижу это так:
1. зашел пользователь, подсоединился т.е. к базе (причем напрямую - из формы, а не из восстановленного по номеру сессии паролю. Это важно для случая, если пользователь поменял пароль).
2. считываем из базы номер сессии для этого пользователя
3. востанавливаем параметры сессии по номеру с винта.
   (их может быть много.. например... ну не знаю... например кол-во записей в базе, что бы показать сколько их добавилось или удалилось с последнего его визита).
4. сверяем с теми, что он передал в форме (например новый пароль: в базу он зашел с ним, а в сессии прописан еще старый, или язык веб-интерфейса)
  4а. если что-либо изменилось - удаляем текущую сессию, удаляем ее номер из базы, происываем новую на винт и запись о ней в базу - отдаем ему его интефейс
 4б. ничего не изменилось - отдаем ему его интерфейс.
--------------------
ну. вот так вот. слишком долго, ресурсоемко. нет?
а, если у меня в базе 50 пользователей, я открываю таблицу сессионс и что, - для КАЖДОГО пользователя в цикле давать права селект, делит, инсерт, апдейт? Или можно как-то сделать это сразу для всех?
Цитировать
Green Kakadu:
и соответственно вытягиваешь все из своей БД.

вы предлагаете все хранить в базе?! гм. тогда зачем мне вообще нужен модуль цги::сессион? ключ я и так могу сгенерить, это не проблема. нет. на мой взгляд - надо хранить именно в сессии. с ключем айпи-матч и еще какой-либо своей "чексамм". т.е. даже если узнают номер сессии (что не так уж и сложно) то пришлось бы постараться дабы пройти проверки в ней установленные.
ух. ;) вон сколько написала
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 11 Июля 2005, 13:26:37
Цитировать
AnnA:
вы предлагаете все хранить в базе?! гм. тогда зачем мне вообще нужен модуль цги::сессион? ключ я и так могу сгенерить, это не проблема. нет. на мой взгляд - надо хранить именно в сессии. с ключем айпи-матч и еще какой-либо своей "чексамм". т.е. даже если узнают номер сессии (что не так уж и сложно) то пришлось бы постараться дабы пройти проверки в ней установленные.

там и так все хранится в базе. Причем это временное хранилище. Вы для сессии созраняете некоторые нужные вам данные, они сериализуются (Dump/Storable) и сохраняются.
А для того, чтоб не было проблем при смене пароля вы должны пользовательские данные (пароль, имя, настройки и т.д.) хранить в отдельном месте ,а не кидать их в таблицу где сохраняются сессии. К тому же сессии полезно подтирать с некоторой периодичностью.
Алгоритм примерно таков:
зашел пользователь, получили его sid, если такая есть, то вы знаете его id и можете из своих таблиц выбрать то, что нужно (или взять это из данных сессии).
Если sid не существует или устарела, то соответственно, он проходит процесс авторизации и вы создаете ему сессию.
Если он меняет какие-либо данные, вы вносите их (туда где хранятся данные пользователей, а не в сессию), удаляете старую сессию, открываете новую. Сессионные данные ВРЕМЕННЫЕ не стоит туда кидать что-то предназначенное для длительного хранения.
примерно так.
Название: Конкретная задача. Сессии на Perl.
Отправлено: AnnA от 11 Июля 2005, 15:44:51
Green Kakadu или мы о разном толкуем, или я вас не понимаю.
Цитировать
Green Kakadu:
там и так все хранится в базе.

да нет же. в базе храняится только пользовательский ИД и номер его сессии.
Цитировать
Green Kakadu:
А для того, чтоб не было проблем при смене пароля вы должны пользовательские данные (пароль, имя, настройки и т.д.) хранить в отдельном месте ,а не кидать их в таблицу где сохраняются сессии

нутк в таблице я и храню ТОЛЬКО номер сессии и ничего более.

Цитировать
Green Kakadu:
Если он меняет какие-либо данные, вы вносите их (туда где хранятся данные пользователей, а не в сессию), удаляете старую сессию, открываете новую.
Ну блин. А зачем мне тогда она вообще нужна эта сессия, если в ней только то и есть, что номерок? Да вы не злитесь, просто не могу понять зачем он мне вообще нужен - номер сессии, если все данные хранятся в БД? Тогда я могу "таскать за собой" по страницам, например ИД пользователя +1024 (например. причем число после + может меняться. это несложно реализовать). м?

Цитировать
Green Kakadu:
Сессионные данные ВРЕМЕННЫЕ не стоит туда кидать что-то предназначенное для длительного хранения.

"Временные" - имеется ввиду $session->expire(\'+1h\');? в ЛЮБОМ случае я получаю файл вида: cgisess_3d4799f72a9f3a20e8bf955687afabe3 вот из него я и пишу в базу ТОЛЬКО  sid -> 3d4799f72a9f3a20e8bf955687afabe3 т.е.
$dbh->do(qq{ insert into SESSIONS values ($user_id, $sid) }) or die $DBI::errstr;
$dbh->commit or die $DBI::errstr;
Название: Конкретная задача. Сессии на Perl.
Отправлено: commander от 11 Июля 2005, 17:50:07
AnnA
Цитировать
"Временные" - имеется ввиду $session->expire(\'+1h\');? в ЛЮБОМ случае я получаю файл вида: cgisess_3d4799f72a9f3a20e8bf955687afabe3 вот из него я и пишу в базу ТОЛЬКО sid -> 3d4799f72a9f3a20e8bf955687afabe3 т.е.
$dbh->do(qq{ insert into SESSIONS values ($user_id, $sid) }) or die $DBI::errstr;
$dbh->commit or die $DBI::errstr;

мда...
"не понимание сути природы..."

зачем использовать файлы и при всем при этом ещё и БД чего то пихать?
Цитировать
Тогда я могу "таскать за собой" по страницам, например ИД пользователя +1024 (например. причем число после + может меняться. это несложно реализовать). м?

ну да... полностью согласен!
вот только маленькое но! если этих параметров с десяток? их тоже будешь с собой по страницам тоскать?
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 11 Июля 2005, 23:09:34
По порядочку. Причем файлы если данные сессии хранятся в БД?
По умолчанию, CGI::Session использует для хранилища файлы, но никто не мешает использовать

БД:
Создаем для этого таблицу:

CREATE TABLE my_sessions (
        id CHAR(32) NOT NULL UNIQUE,
        a_session TEXT NOT NULL
    );

Что тут хранится?
id - уникальный ключ (32 байта) Сгенерированный MD5, SHA1 или способом дедушки на кухне

(модуль Session::ID::Incr)
a_session - это не ид пользователя ,а сериализованные данные (хеш)  в котором хранятся время

жизни, ip (если есть) и т.д. + ПО желанию вы можете внести туда что-то свое через метод

param. Сериализуется все по умолчанию через Data::Dumper (Storable побыстрее, так что если

установлен, то возможно стоит его использовать, задается при создании сессии)

Таблица есть, теперь делаем такие движения:

use CGI::Session;
use CGI qw/:cgi/;
my $cgi = new CGI;
#по умолчанию таблица называется sessions
# если у вас не так, то надо указать имя таблицы:
$CGI::Session::MySQL::TABLE_NAME = \'my_sessions\';
# далее вызываем объект сессии. Если она есть и ее срок не истек, то сответственно получаете

#параметры ессии, если истек или ее нет, то автоматом открывается новая
# Нам он НЕ очень нужен :)
my $s = new CGI::Session("driver:MySQL", $cgi, {Handle=>$dbh});

#Используем это:
#Альтернативный способ "без автоматов" сойдет для авторизации - метод load
my $s = CGI::Session->load("driver:MySQL", $cgi, {Handle=>$dbh});
#проверяем срок годности:
if ( $s->is_expired ) {
#если устарела
   $s->delete();#удаляем ее, чтоб не засорять
        &login;#пусть логинится
        exit(0);
}
    if ( $s->is_empty ) {
   # если ее вообще нет, то пусть тоже логинится
       &login;#пусть логинится
        exit(0);
}
# все кривые ушли на авторизацию, остались живые
# можем получить нужные параметры
my $user_id = $s->param(\'user_id\');#если он конечно нужен
#зададим какой-нибудь параметр:
$s->param(\'my_param\',\'Хоу ду ю ду миссис Джейн?\');
#делаем что угодно, хотя это нам на самом деле и не нужно

# НО нужно продлить время жизни
$s->expire(\'+2h\');#продлеваем время жизни сессии на пару часов
# время жизни сохраняется и в БД, не только в куках
# куки нам вообще неинтересны
#ля-ля-ля
# Только когда будете отдавать пользователю страницу, не забудьте вначале послать заголовки
print $s->header();

При авторизации, вы проверяете пароль, логин и если все прошло успешно, создаете новую

сессию
my $s = new CGI::Session("driver:MySQL", $cgi, {Handle=>$dbh});

Примерно так.

В куках передается только sid и ничего более, все остальное хранится на стороне сервера.
И хранить там из своего по-моему надо только id пользователя, чтоб его опознать и получить

по этому id данные которые хранятся уже в ваших хранилищах (не важно где)
Можно на несколько разных скриптов использовать одну таблицу сессий ,просто разные скрипты

будет искать данные своих пользователях в разных местах.

CGI::Session - это не инструмент для сохранения пользовательских данных, это лишь инструмент

для временного (в течении сеанса или нескольких сеансов) сохранения временных данных с

привязкой к конкретному пользователю.

Лично мне CGI::Session не понравился по нескольким причинам, если говорить о БД:
 универсальность хранения (или в файлах или в БД как хотите) делает его хромым при работе с

БД. Вместо простых SQL запросов для проверки времени истечения жизни сессии, он выбирает

конкретную запись ,восстанавливает сериализованные данные и потом смотрит. Намного лучше,

если бы это значение было в отдельном поле, тогда можно было бы пачкой удалять все

устаревшие сессии, а иначе происходит накопление "мертвых" сессий (один раз вас юзер посетил

, вы ему сделали сессию, и он никогда не вернулся, а в БД запись висит).
Поэтому лучше написать и использовать что-то свое. В случае файлов это не так критично, хотя

тоже захламляется.
Сессии нужно подтирать - это как стикер, написал, повесил на холодильник, через день

прочитал и выкинул. Если понадобилось - взял новую бумажку и там опять накалякал.

P.S. Сорри, если сумбурно, но на развернутуе сочинение how-to пока времени не хватает ,может

соберусь как нибудь..
Название: Конкретная задача. Сессии на Perl.
Отправлено: commander от 12 Июля 2005, 09:42:10
Green Kakadu
Цитировать
Лично мне CGI::Session не понравился

как это знакомо... :) я вообще от готовый решений отказался... свой написал...
Название: Конкретная задача. Сессии на Perl.
Отправлено: AnnA от 12 Июля 2005, 11:14:12
Цитировать
commander:
если этих параметров с десяток?

да хоть с двадцаток. речь шла о том, что ВСЕ параметры хранятся в БАЗЕ. а по страницам передавать только "например ИД пользователя +1024". зачем писать "хоть что-то", если нечего добавить по сути вопроса. непонятно. именно, что
Цитировать
commander:
"не понимание сути природы..."

Green Kakadu respect. "Разжевали, как ребёнку". :super: :chmok:
Название: Конкретная задача. Сессии на Perl.
Отправлено: commander от 12 Июля 2005, 11:22:04
AnnA
Цитировать
что ВСЕ параметры хранятся в БАЗЕ. а по страницам передавать только "например ИД пользователя +1024"

а чем простите тогда у вашего метода принцепиальное отличие от сессий? :)
Цитировать
зачем писать "хоть что-то", если нечего добавить по сути вопроса.

по сути вопроса мне есть что добавить... по этому и пишу... вы в ввиду, видимо своей некомпетентности, пытаетесь изобрести велосипед да ещё и с квадратными колёсами... а я пытаюсь вас предостеречь от этого... не более того...
to moderators:
sorry за флэйм....
Название: Конкретная задача. Сессии на Perl.
Отправлено: NeoNox от 12 Июля 2005, 12:29:23
[moderator]
Я внимательно смотрю за этой веткой.
Постарайтесь держать себя в рамках.
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 12 Июля 2005, 13:35:40
Цитировать
AnnA:
да хоть с двадцаток. речь шла о том, что ВСЕ параметры хранятся в БАЗЕ. а по страницам передавать только "например ИД пользователя +1024".

ничем. поэтому вы сами можете написать нечто ,что будет работать лучше. Передается только sid, он хранится в куках (а можно и по ссылкам таскать)
У CGI::Session просто название такое хорошее, тогда как стандартным модулем для работы с сессиями он не является :)
Название: Конкретная задача. Сессии на Perl.
Отправлено: AnnA от 12 Июля 2005, 13:35:40
дык а тут в общем-то теперь все понятненько. может и не всем, конечно. ;)
Green Kakadu а можно узнать ваше мнение/отношение об/к Apache::Session::MySQL?
насколько я поняла при беглом чтении документации - принцип приблизительно одинаков и для авторизации действительно  
Цитировать
Green Kakadu:
лучше написать и использовать что-то свое


commander извините - у меня нет желания с вами препираться, а по сути вопроса вы так ничего и не сказали. :) спасибо большое за предостережения, но я, в общем-то пытаюсь лишь понять принцип/алгоритм, а вовсе не создавать велосипед.
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 12 Июля 2005, 13:41:38
Цитировать
AnnA:
Green Kakadu а можно узнать ваше мнение/отношение об/к Apache::Session::MySQL?

ничего сказать не могу, не использовал :(
если будете выбирать механизм для поддержки сессий то прежде всего посмотрите на воз-ть очистки (массовой) мертвых сессий, срок которых истек. По идее это один sql запрос на удаление всех сессий у которых поле "срока годности" истекло.
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 12 Июля 2005, 13:50:53
Посмотрел документацию Apache::Session::Store::MySQL
в общем-то хранение ничем не отличается, тот же sid + хеш с данными в a_session
Для построения какого-нибудь частопосещаемого ресурса (например форума) ИМХО не лучший вариант, потому как сериализация данных - ненужное и лишнее телодвижение, когда обычно от сессии требуется воз-ть идентифицировать пользователя ну и узнать служебные параметры сессии (ip ,время), что лучше бы просто вынести в отдельные поля
Название: Конкретная задача. Сессии на Perl.
Отправлено: AnnA от 12 Июля 2005, 15:05:09
Green Kakadu спасибо.
Название: Конкретная задача. Сессии на Perl.
Отправлено: DSA от 14 Июля 2005, 09:01:14
Простите пожалуйста что вмешиваюсь в вашу беседу,но меня тоже очень интересует принцип использования сессий (в моем случае для авторизации/аутентификации на сайте) с помощью модуля CGI::Session. А проблема моя заклчается в том, что я, даже после прочтения здаровенного мануала(туториала), так и не понял, каким образом можно/нужно проверять является ли пользователь "хозяином" сессии? (т.е. тем,кто ее изначально создал в том виде и с тем ключом, с которым она есть).

А я проделываю следующее:

my $cgi = new CGI;
my $cookie;
my $sid = $cgi->cookie("CGISESSID") || undef;
my $session = new CGI::Session(undef, $sid, {Directory=>\'Z:/tmp\'});

unless ($sid) {
 $cookie = $cgi->cookie(CGISESSID => $session->id);
 print $cgi->header(-cookie=>$cookie);
}

Это в основном вырезки из туториала. Но вот мне не совсем понятно каким образом происходит АУТЕНТИФИКАЦИЯ. Тоесть определения честности пользователя. И что происходит, когда в качестве второго параметра в конструктор CGI::Session передается значение, не равное undef? Тоесть если undef, насколько я понял, создается новая сессия, а если нет? Есть ли тогда вообще смысл в этой часте кода при $sid не undef? (... new CGI::Session(undef, $sid, {Directory=>\'Z:/tmp\'});

Заранее спасибо за возможные ответы или критику или даже игнор :)
Название: Конкретная задача. Сессии на Perl.
Отправлено: DSA от 14 Июля 2005, 11:54:46
Я вот впринципе подумал и мне на ум приходит только один вариант решения данной проблемы. Вот примерный алгоритм:
 1. Юзер вводит логин и пароль, нажимает ок.
 2. Скрипт проверяет пользователя по базе, если все ок, пользователь существует и пароль верен, то отправляем на главную страницу некого интерфейса.
 3. На главной странице создается сессия выше указанным способом(если кукиса нет,то создаем, если есть,пользуемся текущей).
 4. Далее, допустим,при перемещении в какой-либо секретный раздел(тоесть раздел защищенного интерфейса), то мы делаем следующее:
        4.1  Проверяем пользователя кукисы. Записываем кукис с именем CGISESSID в некую переменную (если он есть). Эта часть кода у меня так выглядит:

my $sid = $cgi->cookie("CGISESSID") || undef;

if ($sid) {
 my $session = new CGI::Session(undef, $cgi, {Directory=>\'Z:/tmp\'});
 print "Okey!
";
 print "Session->ID = ", $session->id(), "
;
} else {
 print "nefiga :(
";
}

Вот и все. Но мне почему-то кажеться что существует какой-то другой, более элегантный способ проверки.
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 14 Июля 2005, 15:07:03
Цитировать
DSA:
Простите пожалуйста что вмешиваюсь в вашу беседу,но меня тоже очень интересует принцип использования сессий (в моем случае для авторизации/аутентификации на сайте) с помощью модуля CGI::Session. А проблема моя заклчается в том, что я, даже после прочтения здаровенного мануала(туториала), так и не понял, каким образом можно/нужно проверять является ли пользователь "хозяином" сессии? (т.е. тем,кто ее изначально создал в том виде и с тем ключом, с которым она есть).

почитай то что я подробно написал в этом топике выше (с прмером):
http://forums.webscript.ru/showthread.php?s=&postid=129870#post129870

Как определяется пользователь владелец сессии? По sid - ид-ру сессии
Цитировать
DSA:
Вот и все. Но мне почему-то кажеться что существует какой-то другой, более элегантный способ проверки.

да, потому как все это делает CGI::Session самостоятельно (метода load , new)
В том числе и отправку куков, модуль делает сам $session->header
почитайте мой пост выше я там подробно расписал это
Название: Конкретная задача. Сессии на Perl.
Отправлено: DSA от 14 Июля 2005, 23:32:18
Большое спасибо за ответ, Зеленый Какаду! :-)
Мне очень понравился ваш развернутый, подробный ответ, но я почему-то не нашел в перловой документации ничего про метод load, да и при попытке использовать его в скрипте перл ругается:

Can\'t locate auto/CGI/Session/load.al in @INC (@INC contains: z:/usr/lib z:/usr/
site/lib .) at xxx.pl line 7

Не могли бы ли вы прислать его мне на мыло mailbest@ru.ru либо скинуть прямо сюда в виде открытого кода? (я думаю он будет не большой по содержанию), я был бы очень признателен.

Кстати, вы писали, что вас лично модуль CGI::Session не устраивает, т.к. "Вместо простых SQL запросов для проверки времени истечения жизни сессии, он выбирает конкретную запись ,восстанавливает сериализованные данные и потом смотрит." - а нельзя ли написать собственную функцию отчистки базы от "мертвых" сессий? Тоесть срок действия которых давно истек.
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 15 Июля 2005, 00:36:33
Цитировать
DSA:
ничего про метод load, да и при попытке использовать его в скрипте перл ругается:

Can\'t locate auto/CGI/Session/load.al in @INC (@INC contains: z:/usr/lib z:/usr/ site/lib .) at xxx.pl line 7

сорри :) не сказал, что я смотрел уже новую версию (она еще в процессе разработки):
http://search.cpan.org/~sherzodr/CGI-Session-4.00_08/

Цитировать
DSA:
Кстати, вы писали, что вас лично модуль CGI::Session не устраивает, т.к. "Вместо простых SQL запросов для проверки времени истечения жизни сессии, он выбирает конкретную запись ,восстанавливает сериализованные данные и потом смотрит." - а нельзя ли написать собственную функцию отчистки базы от "мертвых" сессий? Тоесть срок действия которых давно истек.

можно конечно, только это будет мягко говоря "не опримальный" вариант:
т.к. дата истечения хранится в хеше, который в свою очередь через Dump/Storable превращен в строку текста, то придется вытаскивать данные a_session для каждой сессии,восстанавливать эти данные, проверять время истечения и потом уже если оно истекло удалять.
Самый лучший вариант вынести это в отдельное поле (т.е. переписать некоторые методы CGI::Session::Driver::mysql + добавить парочку своих для массовой проверки/удаления), но ИМХО проще тогда написать свой вариант.
Название: Конкретная задача. Сессии на Perl.
Отправлено: Green Kakadu от 15 Июля 2005, 00:44:46
Цитировать
Green Kakadu:
Самый лучший вариант вынести это в отдельное поле (т.е. переписать некоторые методы CGI::Session::Driver::mysql + добавить парочку своих для массовой проверки/удаления), но ИМХО проще тогда написать свой вариант.

оказывается это уже сделали (правда для PostgreSQL):
CGI::Session::PureSQL (http://search.cpan.org/~markstos/CGI-Session-PureSQL-0.54/)
Там используется таблица вида:
    -- This syntax for for Postgres; flavor to taste
    CREATE TABLE sessions (
        session_id               CHAR(32) NOT NULL,
                remote_addr              inet,
                creation_time    timestamp,
                last_access_time timestamp,
                duration                 interval
    );
Название: Конкретная задача. Сессии на Perl.
Отправлено: DSA от 15 Июля 2005, 14:45:59
Вау! Пасибки за ценнейшую информацию :) Пойду прямо сейчас обновлять свою 3-95 на 4 версию CGI::Session :)