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

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

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

7 ответов

Решение

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

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

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

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

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

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

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

Vary: Cookie

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

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

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

      // Removes all site data
response.setHeader ("Clear-Site-Data", "\"cache\"");

Подробнее об этом здесь: читайтеhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data

Альтернативой реализации фильтра является установка фильтра «без кеширования» для всех защищенных JSP или для всех путей. Это может быть хорошей идеей, если приложение небольшое и вы хотите настроить это свойство только для определенных страниц. Мы можем добавить следующий фрагмент кода Java в каждый защищенный JSP, который не следует кэшировать:

      <%
  response.addHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  response.setDateHeader("Expires", 0);
%>

Если не в JSP, это также можно использовать в контроллерах, где определена маршрутизация, и установить заголовки для объекта «HttpServletResponse».

Другие вопросы по тегам