Забороніть користувачеві бачити раніше відвідану захищену сторінку після виходу


99

У мене є вимога, щоб кінцевий користувач не міг повертатися на сторінку з обмеженими можливостями після виходу / виходу. Але в даний час кінцевий користувач може це зробити за допомогою кнопки повернення браузера, відвідування історії браузера або навіть шляхом повторного введення URL-адреси в адресному рядку браузера.

В основному, я хочу, щоб кінцевий користувач не міг жодним чином отримувати доступ до сторінки з обмеженим доступом після виходу. Як я можу досягти цього найкращого? Чи можна відключити кнопку назад за допомогою JavaScript?


7
Скористайтеся шаблоном після отримання запиту. Отримайте його.

Відповіді:


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 Я створив окремий клас Filter, щоб замінити doFilter()метод. Коли я натискаю кнопку виходу, він переспрямовується на сервлет, де в інваліді запускається сеанс. Я не впевнений, як doFilter()тут грає метод. Скажіть, будь ласка, як це здійснити? Як і в, правильні кроки, які слід виконати. Дякую.
Анян Барадвай

Добре працював для мене. Випробуваний після sendRedirect(...)і forward().
Hal50000

5

* .jsp в Url Pattern не працюватиме, якщо переслати сторінку. Спробуйте включити і ваш сервлет .., що зробить вашу програму захищеною від цієї проблеми із кнопкою "назад".


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
Хоча ваша відповідь є корисною, будь ласка, опублікуйте відповідь, що стосується мови програмування ОП на вибір. Ваше рішення C # не допоможе в проекті Java EE OP.
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.