Evitar que el usuario vea una página segura visitada anteriormente después de cerrar la sesión


99

Tengo el requisito de que el usuario final no pueda volver a la página restringida después de cerrar sesión. Pero actualmente, el usuario final puede hacerlo mediante el botón Atrás del navegador, visitando el historial del navegador o incluso volviendo a ingresar la URL en la barra de direcciones del navegador.

Básicamente, quiero que el usuario final no pueda acceder a la página restringida de ninguna manera después de cerrar sesión. ¿Cómo puedo lograr esto mejor? ¿Puedo desactivar el botón Atrás con JavaScript?


7
Utilice el patrón Post-request-get.

Respuestas:


137

Puede y no debe desactivar el botón de retroceso o el historial del navegador. Eso es malo para la experiencia del usuario. Hay hacks de JavaScript, pero no son confiables y tampoco funcionarán cuando el cliente tenga JS deshabilitado.

Su problema concreto es que la página solicitada se cargó desde la caché del navegador en lugar de directamente desde el servidor. Esto es esencialmente inofensivo, pero de hecho confunde al usuario final, porque él / ella piensa incorrectamente que realmente proviene del servidor.

Solo necesita indicarle al navegador que no almacene en caché todas las páginas JSP restringidas (y, por lo tanto, no solo la página / acción de cierre de sesión en sí). De esta manera, el navegador se ve obligado a solicitar la página del servidor en lugar de la caché y, por lo tanto, se ejecutarán todas las comprobaciones de inicio de sesión en el servidor. Puede hacer esto usando un filtro que establece los encabezados de respuesta necesarios en el doFilter()método:

@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);
    }

    // ...
}

Mapee esto Filteren un lugar url-patternde interés, por ejemplo *.jsp.

@WebFilter("*.jsp")

O si desea poner esta restricción solo en páginas seguras, debe especificar un patrón de URL que cubra todas esas páginas seguras. Por ejemplo, cuando todos están en la carpeta /app, debe especificar el patrón de URL de /app/*.

@WebFilter("/app/*")

Aún más, puede hacer este trabajo en el mismo lugar Filterdonde está verificando la presencia del usuario que inició sesión.

¡No olvide borrar la memoria caché del navegador antes de realizar la prueba! ;)

Ver también:


2
A veces esto no es suficiente, recuerdo haber tenido ese problema. El navegador simplemente recuerda la última página. Pero podría haber sido IE6, no puedo recordar :)
Bozho

3
@Bozho: O ha proporcionado un conjunto incompleto de encabezados o el navegador tiene la página todavía en su caché.
BalusC

1
@Chris: me funciona con Firefox y todos los demás navegadores. Su problema se debe a otra causa. ¿Quizás olvidó borrar algo de caché? ¿O esos encabezados están configurados con respuestas incorrectas?
BalusC

@BalusC Creé una clase Filter separada para anular el doFilter()método. Cuando presiono el botón de cierre de sesión, se redirige a un servlet en el que invalido la sesión. No estoy seguro de cómo doFilter()entra en juego el método aquí. ¿Puede decirme cómo implementar esto? Como en, los pasos correctos a seguir. Gracias.
Anjan Baradwaj

Me funcionó bien. Probado después de ambos sendRedirect(...)y forward().
Hal50000

5

* .jsp en Url Pattern no funcionará si reenvía una página. Intente incluir su servlet también ... eso hará que su aplicación esté segura de este problema del botón de retroceso.


2

La forma más sencilla de hacerlo sin deshabilitar el botón de retroceso del navegador es agregar este código al page_loadevento de la página a la que no desea que el usuario vuelva después de cerrar la sesión:

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
Aunque su respuesta es útil, publique la respuesta que se relacione con el lenguaje de programación elegido por el OP. Su solución C # no ayudará en el proyecto Java EE de OP.
Buhake Sindi

0

Puede intentar decirle al navegador que no almacene en caché la página de inicio (usando los encabezados apropiados - Expires, Cache-Control, Pragma). Pero no se garantiza que funcione. Lo que puede hacer es realizar una llamada ajax al servidor en la carga de la página para verificar si el usuario está registrado, y si no, redirigir.


13
Pero si una mente maligna deshabilita JavaScript, esto no funciona y, sin embargo, verá la página.
acme

0

La forma correcta de hacer esto es agregar el

Vary: Cookie

encabezado en páginas seguras. Cuando el usuario cierre la sesión, borre su cookie de sesión. Luego, cuando naveguen hacia atrás después de cerrar la sesión, el caché del navegador fallará. Esto también tiene la ventaja de no anular completamente el almacenamiento en caché.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.