Я делаю простой форум с серией Servlets
то, что каждый представляет дом, тему, постредактирование, вход в систему и userlist страницу. На некоторых из этих страниц существует ссылка, которая появляется, когда пользователь не зарегистрирован.
То, чего я хотел бы достигнуть, должно инициировать перенаправление (использующий вперед () на RequestDispatcher) после входа в систему, таким образом, браузер возвращается к странице, где пользователь прежде нажимал на ссылку входа в систему. Чтобы сделать это, я вижу два решения.
Первое решение состоит в том, чтобы иметь HTML Form
с кнопкой входа в систему и невидимым полем, которое будет содержать информацию, которая скажет что страницу перенаправить как a Parameter
. Это выполнимо, но я хотел бы попробовать что-то еще.
Второе решение состоит в том, чтобы добавить Attribute
к session
это представляет первую "страницу" в некотором роде. Это могло содержать Строку, но это не отличается от первого подхода. Другое скручивание должно было бы добавить ссылку на HttpServlet и использовать instanceof или статическую Строковую переменную, которая могла использоваться для идентификации Сервлета в некотором роде. Однако это потребовало бы создания класса общего предка для весь Servlets
.
Возможно, существует другое простое решение, что Вы видите, что это сформировало бы хороший компромисс? Или, возможно, одно из вышеупомянутых решений совершенно приемлемо?
Я бы предпочел первое решение второму. Это запрос информации в области видимости и действительно не относится к сеансу, это приведет только к "wtf?" опыт, когда у вас открыто несколько окон / вкладок в одном сеансе.
В ссылке на страницу входа просто передайте текущий URL в качестве параметра запроса:
<a href="/login?from=${pageContext.request.requestURI}">Login</a>
Или, если это форма POST для страницы входа:
<input type="hidden" name="from" value="${pageContext.request.requestURI}">
В форме входа в систему передайте ее в следующий запрос как скрытую переменную:
<input type="hidden" name="from" value="${param.from}">
В сервлете входа используйте ее:
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getParameter("from"));
} else {
// Show error.
}
Довольно просто, не правда ли? :)
Некоторые могут предложить использовать request.getHeader ("referer")
для этого внутри формы входа вместо request.getRequestURI ()
в ссылке / кнопке перед входом , но я бы не стал этого делать, так как это контролируется клиентом и не t всегда возвращать достоверную информацию. Некоторые клиенты отключили его или используют какое-то программное обеспечение, которое подменяет его недопустимым значением, например, большинство продуктов Symantec ( cough ).
из: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity.pdf
глава: Поток приложения при успешной и неудачной аутентификации
... Если аутентификация прошла успешно, полученный объект аутентификации будет помещен в SecurityContextHolder. Настроенный AuthenticationSuccessHandler затем будет вызван для перенаправления или переадресации пользователя в подходящее место назначения. По умолчанию используется SavedRequestAwareAuthenticationSuccessHandler, что означает, что пользователь будет перенаправлен в исходное место назначения, которое они запросили, прежде чем его попросят войти в систему. ...
Использование скрытого поля в форме довольно стандартно. Зачем пытаться изобретать велосипед?
Ваш первый предложенный подход является лучшим. Создайте скрытое поле с value = request.getRequestURI ()
и перенаправьте на этот URI после входа в систему.
Использование referer
не будет работать, потому что IE (по крайней мере, некоторые из его версии) не устанавливает заголовок referer
.
Сохранение параметра в сеансе может вызвать странное поведение, если пользователь открывает несколько вкладок.
Изменить: Чтобы лучше проиллюстрировать вопрос:
некоторый ресурс -> (запрашивает защищенный ресурс) -> (перенаправляется на страницу входа в систему) -> (должен быть перенаправлен на исходный ресурс)
В большинстве ответов предполагается, что «вход в систему» нажимается ссылка / кнопка, а затем открывается страница входа в систему. Это только одна сторона дела. В этом случае исходный URL ресурса может быть добавлен в качестве параметра и помещен в форму входа (в скрытом поле).
Но в случае перенаправления с защищенного ресурса на страницу входа, скрытое поле должно содержать URL немедленного запроса.
Это, конечно, не то, о чем идет речь, но со временем возникнет ситуация, и ее также следует учитывать.
Если хотите чтобы сделать это со страницами, ваша страница входа может посмотреть на заголовок referer (sic) в запросе, который его загрузил ( request.getHeader ("referer")
), чтобы узнать, является ли это страницей вашего сайта ( если нет - или если заголовок отсутствует - используйте какое-то значение по умолчанию). Затем он сохранит этот URL-адрес (я бы, вероятно, использовал скрытое поле, как вы сказали, в форме входа в систему; но переменная сеанса тоже будет работать). По завершении входа в систему выполните перенаправление на сохраненный URL.
В наши дни я ' Я, вероятно, использовал бы все это как резервный механизм, если бы я не мог выполнить вход, наложив диалоговое окно на страницу и войдя в систему через Ajax - и, следовательно, никогда не покидая страницу вообще.
Изменить Или еще лучше, как указывает Божо, закодировать целевую страницу в свою ссылку на страницу входа. Хотя неверно , что IE не устанавливает заголовок "referer" (а он устанавливает), referer не требуется и может быть отключен, и поскольку вы уже динамически создаете страницу, ссылающуюся на форму входа в систему , зачем быть уязвимым для этого, если вам не нужно быть уязвимым.
Хорошо, вот что я сделал. Логин - это двухступенчатый процесс, при котором один сервлет показывает форму, а другой контролирует, правильна ли комбинация имя пользователя+пароль. Эти два могут быть объединены.
Параметр может быть отправлен через форму или по ссылке (JSP еще не добавлен): Затем параметр извлекается следующим образом:
String comeback = request.getParameter("comeback");
После проверки регистрационной информации, переадресация может быть выполнена следующим образом:
RequestDispatcher rd = request.getRequestDispatcher( redirectionPath );
if( rd != null )
rd.forward(request, response);