Каков наилучший метод сохранения действия для приложения Catalyst? - PullRequest
8 голосов
/ 07 января 2009

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

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

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

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

Существуют ли стандартные «лучшие практики» или кулинарная книга, как это сделать?

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

Ответы [ 5 ]

4 голосов
/ 07 января 2009

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

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

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

Это похоже на грязную ситуацию, и я склонен повторить мое первое предложение ...

UPDATE:

Независимо от того, используете ли вы 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) или аналогичный. Возможно, отметка времени, чтобы не было восстановлено ничего слишком устаревшего. Вы также можете сохранить действие, которое вы обрабатывали, чтобы убедиться, что найденные элементы формы принадлежат правильной форме. Вы знаете проблемы для своего приложения лучше меня.

2 голосов
/ 07 января 2009

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

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

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

1 голос
/ 21 февраля 2009

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

1 голос
/ 13 января 2009

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

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

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

0 голосов
/ 07 января 2009

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

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

...