Сохранение данных HTTP POST, когда запрос прерывается страницей входа в систему

Допустим, пользователь просматривает веб-сайт, а затем выполняет какое-то действие, которое изменяет базу данных (допустим, они добавляют комментарий). Однако когда приходит запрос на добавление комментария, мы обнаруживаем, что нам нужно заставить их войти в систему, прежде чем они смогут продолжить.

Предположим, что страница входа в систему запрашивает имя пользователя и пароль и перенаправляет пользователя обратно на URL-адрес, по которому они переходили, когда вход был необходим. Это перенаправление работает с поиском URL-адреса только с параметрами GET, но если запрос изначально содержал некоторые данные HTTP POST, теперь они теряются.

Может ли кто-нибудь порекомендовать способ справиться с этим сценарием, когда задействованы данные HTTP POST?

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


Изменить: одно дополнительное ограничение, которое я должен был прояснить. Представьте, что мы не знаем, потребуется ли вход в систему, пока пользователь не отправит свой комментарий. Например, их cookie мог истечь между тем, как они загрузили форму, и фактически отправили комментарий.


person Matt Sheppard    schedule 10.09.2008    source источник


Ответы (6)


2 варианта:

  1. Запишите беспорядочную форму со страницы входа и добавьте ее на страницу с помощью JavaScript form.submit ().
  2. Выполните POST-запрос страницы входа на запрашивающую страницу (с предыдущими значениями) и пусть контроллер этой страницы выполнит проверку входа. Включите это в любую логику, которая у вас уже есть для обнаружения не вошедшего в систему пользователя (структуры различаются в зависимости от того, как они это делают). В псевдо-MVC:

        CommentController {
           void AddComment() {
             if (!Request.User.IsAuthenticated && !AuthenticateUser()) {
                return;
             }
             // add comment to database
           }

           bool AuthenticateUser() {
             if (Request.Form["username"] == "") {
                // show login page
                foreach (Key key in Request.Form) {
                   // copy form values
                   ViewData.Form.Add("hidden", key, Request.Form[key]);
                }
                ViewData.Form.Action = Request.Url;

                ShowLoginView();
                return false;
              } else {
                 // validate login
                 return TryLogin(Request.Form["username"], Request.Form["password"]);
              } 
           }
        }
person Mark Brackett    schedule 10.09.2008

Это хорошее место, где могут оказаться полезными методы Ajax. Когда пользователь нажимает кнопку отправки, отобразите диалоговое окно входа в систему на стороне клиента и подтвердите его на сервере перед фактической отправкой страницы.

Другой способ, который я могу придумать, - это динамическое отображение или скрытие элементов управления входом в тег DIV на самой главной странице.

person Gulzar Nazim    schedule 10.09.2008

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

person Jacob Rigby    schedule 10.09.2008

Просто сохраните все необходимые данные из POST в сеансе до завершения процесса входа в систему. Или есть какая-то временная таблица в базе данных для хранения, а затем извлечения ее. Очевидно, это псевдокод, но:

if ( !loggedIn ) {
    StorePostInSession();
    ShowLoginForm();
}

if ( postIsStored ) {
    RetrievePostFromSession();
}

Или что-то вдоль этих линий.

person Robert Swisher    schedule 10.09.2008

Соберите данные на странице, которую они отправили, и сохраните их в своем бэкэнде (базе данных?), Пока они пройдут через последовательность входа в систему, скройте идентификатор транзакции или что-то подобное на странице с формой входа. Когда они будут готовы, верните их на запрашиваемую страницу, выполнив поиск по идентификатору транзакции на бэкэнде, и выгрузите все данные, которые они отправили в форму, для повторного предварительного просмотра, или просто запустите любой код, который будет запускаться на этой странице.

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

person castaway    schedule 10.09.2008

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

Изменить: вы также можете использовать сеанс, как указано, но я почти уверен, что если вы используете пересылку в Java обратно на страницу входа, атрибут запроса будет сохраняться.

person Community    schedule 10.09.2008