Запретить пользователю видеть ранее посещенную защищенную страницу после выхода из системы


99

У меня есть требование, чтобы конечный пользователь не мог вернуться на страницу с ограниченным доступом после выхода / выхода. Но в настоящее время конечный пользователь может сделать это, нажав кнопку «Назад» в браузере, посетив историю браузера или даже повторно введя URL-адрес в адресной строке браузера.

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


7
Используйте шаблон Post-request-get. Погуглите.

Ответы:


137

Вы можете и не должны отключать в браузере кнопку «Назад» или историю. Это плохо для пользовательского опыта. Есть хаки JavaScript, но они ненадежны и не будут работать, когда у клиента отключен JS.

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

Вам просто нужно указать браузеру не кэшировать все ограниченные страницы JSP (и, следовательно, не только страницу / действие выхода из системы!). Таким образом, браузер вынужден запрашивать страницу с сервера, а не из кеша, и, следовательно, все проверки входа на сервер будут выполнены. Вы можете сделать это с помощью фильтра, который устанавливает необходимые заголовки ответа в doFilter()методе:

@WebFilter
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        response.setDateHeader("Expires", 0); // Proxies.

        chain.doFilter(req, res);
    }

    // ...
}

Например, сопоставьте это Filterс url-patternинтересующим *.jsp.

@WebFilter("*.jsp")

Или, если вы хотите наложить это ограничение только на защищенные страницы, вы должны указать шаблон URL, который охватывает все эти защищенные страницы. Например, когда все они находятся в папке /app, вам нужно указать шаблон URL-адреса /app/*.

@WebFilter("/app/*")

Более того, вы можете выполнять эту работу в том же Filter где вы проверяете присутствие вошедшего в систему пользователя.

Не забудьте очистить кеш браузера перед тестированием! ;)

Смотрите также:


2
Иногда этого бывает недостаточно, я помню, была такая проблема. Браузер просто запоминает последнюю страницу. Но это мог быть IE6, не припомню :)
Божо

3
@Bozho: Либо вы предоставили неполный набор заголовков, либо страница браузера все еще находится в кеше.
BalusC

1
@Chris: у меня работает с Firefox и всеми другими браузерами. Ваша проблема вызвана в другом месте. Возможно, вы забыли очистить кеш? Или эти заголовки установлены на неправильные ответы?
BalusC

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

Хорошо сработал для меня. Испытано после того, как sendRedirect(...)и forward().
Hal50000

5

* .jsp в шаблоне URL не будет работать, если вы пересылаете страницу. Попробуйте также включить свой сервлет ... это защитит ваше приложение от этой проблемы с кнопкой возврата.


2

Самый простой способ сделать это, не отключая браузер, - это добавить этот код в page_loadсобытие для страницы, на которую вы не хотите, чтобы пользователь возвращался после выхода из системы:

if (!IsPostBack)
    {
        if (Session["userId"] == null)
        {
            Response.Redirect("Login.aspx");
        }
        else
        {
        Response.ClearHeaders();
        Response.ClearContent();
        Response.Clear();
        Session.Abandon();
        Session.Remove("\\w+");
        Response.AddHeader("Cache-Control", "no-cache, no-store, max-age = 0, must-revalidate");
        Response.AddHeader("Pragma", "no-cache");
        Response.AddHeader("Expires", "0");
        }
    }

6
Хотя ваш ответ полезен, опубликуйте ответ, который относится к выбранному вами языку программирования OP. Ваше решение C # не поможет в проекте OP Java EE.
Buhake Sindi

0

Вы можете попробовать запретить браузеру кэшировать домашнюю страницу (используя соответствующие заголовки - Expires, Cache-Control, Pragma). Но это не гарантирует работу. Что вы можете сделать, так это сделать ajax-вызов серверу при загрузке страницы, чтобы проверить, вошел ли пользователь в систему, а если нет - перенаправить.


13
Но если злой разум отключит JavaScript, это не сработает, и он все равно увидит страницу.
acme

0

Правильный способ сделать это - добавить

Vary: Cookie

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.