Какой самый лучший метод сохранения действий для приложения Catalyst?

Я пишу приложение Catalyst, для которого требуется довольно короткий срок действия сеанса (15 минут). Я использую стандартные модули аутентификации фреймворка Catalyst, поэтому пользовательские данные хранятся в сеансе, т. Е. По истечении срока действия сеанса вы выходите из системы.

Для выполнения многих случаев использования этого приложения потребуется> 15 минут, поэтому пользователи часто отправляют форму только для того, чтобы обнаружить, что состояние их сеанса исчезло, и им необходимо снова войти в систему.

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

У меня есть аутентификационный материал, который обрабатывается методом auto () в контроллере - если вы запрашиваете действие, требующее аутентификации, и вы в данный момент не вошли в систему, вы будете перенаправлены на метод login (), который отображает форма входа в систему, а затем обрабатывает ее после отправки. Кажется, что должна быть возможность сохранить запрос и любые параметры формы, когда автоматический метод перенаправляет на login (), а затем вытащить их обратно, если login () завершится успешно, но я не совсем уверен в лучшем способ получить или сохранить эту информацию обычным / стандартным / многоразовым способом. (Я рассчитываю сохранить его в сеансе, а затем удалить его, когда он будет извлечен обратно; если это кажется плохой идеей, это еще одна проблема.)

Есть ли для этого стандартный "передовой опыт" или поваренная книга?

(Одна морщина: эти формы отправляются через POST.)


person genehack    schedule 06.01.2009    source источник


Ответы (5)


Я не могу избавиться от мысли, что есть фундаментальный недостаток в обязательном 15-минутном тайм-ауте в приложении, которое обычно требует> 15 минут между действиями.

Как бы то ни было, я бы посмотрел на переопределение метода Catalyst::Plugin::Session->delete_session, чтобы любое содержимое $c->request->body_parameters было сериализовано и сохранено (предположительно в базе данных) для последующего восстановления. Возможно, вам понадобится элементарная проверка аргументов POST, чтобы убедиться, что они соответствуют вашим ожиданиям.

Точно так же create_session должен взять на себя ответственность за извлечение этих данных из базы данных и за их доступность для действия исходной формы.

Это действительно неприятная ситуация, и я склонен повторить свое первое предложение ...

ОБНОВИТЬ:

Независимо от того, используете ли вы delete_session или auto, остается парадоксальная проблема: вы не можете сохранить эту информацию в сеансе, потому что событие тайм-аута уничтожит сеанс. Вы должны сохранить его в более постоянном месте, чтобы он пережил повторную инициализацию сеанса. Catalyst::Plugin::Session сам использует Storable, и вы сможете с чем-то в этом роде:

use Storable;
...
sub auto {
    ...
    unless (...) { #ie don't do this if processing the login action
        my $formitems = freeze $c->request->body_parameters;
        my $freezer = $rs->update_or_create(
              {user => $c->user, formitems => $formitems} );
        # Don't quote me on the exact syntax, I don't use DBIx::Class
    }
    ...
    my $formitems = $c->request->body_parameters
                  || thaw $rs->find({$user => $c->user})->formitems
                  || {} ;
    # use formitems instead of $c->request->body_parameters from here on in

В базовой таблице, вероятно, есть (пользовательский CHAR (x), formitems TEXT) или аналогичный. Возможно, это временная метка, чтобы не было восстановлено ничего слишком устаревшего. Вы также можете сохранить обработанное действие, чтобы убедиться, что полученные элементы формы принадлежат правильной форме. Вы лучше меня разбираетесь в проблемах своего приложения.

person RET    schedule 07.01.2009
comment
Что касается фундаментального недостатка, то это проблемы, с которыми человек сталкивается при работе на правительства - я действительно не должен больше говорить. Однако возиться с сеансами мне кажется неправильным, и я исправлю этот вопрос с моими рассуждениями. - person genehack; 07.01.2009
comment
Я также работаю в правительстве, я вас слышу ;-) Если вы сможете встроить логику, которую я описал в автоматическое действие MyApp- ›, тем лучше. Я предполагал, что эта логика будет распространена на многие контроллеры и действия, отсюда и предложение отменить обработку сеанса по умолчанию. Я тоже пересмотрел ответ. - person RET; 07.01.2009

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

Catalyst :: Plugin :: Session :: PerUser - это один из способов сделать это (хотя и несколько хакерски). Я бы рекомендовал использовать плагин сеанса только для аутентификации и хранения всей информации о состоянии в модели, которая вместо этого хранит ваши пользовательские данные.

И я полностью согласен с мнением RET о том, что ограничение в 15 минут кажется в данном контексте контрпродуктивным.

person Community    schedule 07.01.2009

Я наткнулся на это, когда искал в CPAN что-то совершенно не связанное с этим.

Catalyst :: Plugin :: Wizard призван делать именно то, что вам нужно. . В документации предполагается, что он может перенаправлять на страницу входа, сохраняя при этом состояние предыдущего действия.

NB: Я не использовал его, поэтому не могу поручиться за его эффективность.

person RET    schedule 12.01.2009

В конце концов, мы получили ожидающий запрос (URL + params) в auto (), сериализовали и зашифровали его и передали через скрытый элемент формы на странице входа. Если мы получили запрос на вход с заполненным скрытым элементом, мы его расшифровали и десериализовали, а затем соответствующим образом перенаправили (убедитесь, что прошли стандартные пути кода «может ли этот пользователь сделать это»).

person genehack    schedule 21.02.2009
comment
Вы только что полностью отменили истечение срока действия сеанса? - person Kenny Evitt; 15.06.2010

У вас всегда может быть какой-нибудь javascript на клиенте, который предотвращает истечение срока сеанса, делая небольшой запрос каждые несколько минут.

Или у вас может быть AJAX-проверка активного сеанса перед отправкой формы и представлением пользователю нового поля входа в это время, если это необходимо.

person Chuck Phillips    schedule 07.01.2009
comment
Как это мини-приложение для ПК, которое перемещает мышь во время простоя, чтобы не запускать заставку? Почему-то я не думаю, что покупатель сочтет это приемлемым. - person RET; 07.01.2009
comment
Не понимаю, почему бы и нет. Добавление некоторого количества AJAX на страницу звучит проще, чем переопределение методов Catalyst и сохранение данных. Даже если вам все равно нужно принудительно установить короткий тайм-аут, код, стоящий за кнопкой отправки, может проверить, вышли ли вы из системы, и предоставить вам форму входа, если она есть. - person Chuck Phillips; 08.01.2009