Impedire all'utente di visualizzare la pagina protetta visitata in precedenza dopo il logout


99

Ho il requisito che l'utente finale non possa tornare alla pagina con restrizioni dopo il logout / disconnessione. Ma attualmente l'utente finale è in grado di farlo tramite il pulsante Indietro del browser, visitando la cronologia del browser o anche reinserendo l'URL nella barra degli indirizzi del browser.

Fondamentalmente, voglio che l'utente finale non sia in grado di accedere alla pagina con restrizioni in alcun modo dopo essersi disconnesso. Come posso ottenerlo al meglio? Posso disabilitare il pulsante Indietro con JavaScript?


7
Utilizza il pattern Post-request-get. Google it.

Risposte:


137

Puoi e non devi disabilitare il pulsante Indietro o la cronologia del browser. È un male per l'esperienza dell'utente. Esistono hack JavaScript, ma non sono affidabili e non funzioneranno nemmeno quando il client ha JS disabilitato.

Il tuo problema concreto è che la pagina richiesta è stata caricata dalla cache del browser invece che direttamente dal server. Questo è essenzialmente innocuo, ma in effetti confonde l'utente finale, perché pensa erroneamente che provenga davvero dal server.

Devi solo istruire il browser a non memorizzare nella cache tutte le pagine JSP limitate (e quindi non solo la pagina / azione di logout stessa!). In questo modo il browser è costretto a richiedere la pagina dal server invece che dalla cache e quindi verranno eseguiti tutti i controlli di login sul server. Puoi farlo utilizzando un filtro che imposta le intestazioni di risposta necessarie nel doFilter()metodo:

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

    // ...
}

Mappa questo Filtersu un url-patterninteresse, per esempio *.jsp.

@WebFilter("*.jsp")

Oppure, se si desidera applicare questa restrizione solo alle pagine protette, è necessario specificare un pattern URL che copra tutte quelle pagine protette. Ad esempio, quando sono tutti nella cartella /app, è necessario specificare il pattern URL di /app/*.

@WebFilter("/app/*")

Inoltre, puoi fare questo lavoro nello stesso modo Filterin cui stai controllando la presenza dell'utente connesso.

Non dimenticare di svuotare la cache del browser prima di eseguire il test! ;)

Guarda anche:


2
A volte questo non è abbastanza, ricordo di aver avuto un problema del genere. Il browser ricorda solo l'ultima pagina. Ma potrebbe essere stato IE6, non ricordo :)
Bozho

3
@ Bozho: o hai fornito un set incompleto di intestazioni o il browser ha la pagina ancora nella sua cache.
BalusC

1
@ Chris: funziona per me con Firefox e tutti gli altri browser. Il tuo problema è causato altrove. Forse hai dimenticato di svuotare un po 'di cache? O quelle intestazioni sono impostate sulle risposte sbagliate?
BalusC

@BalusC Ho creato una classe Filter separata per sovrascrivere il doFilter()metodo. Quando premo il pulsante di logout viene reindirizzato a un servlet dove invalido la sessione. Non sono sicuro di come il doFilter()metodo entri in gioco qui. Puoi dirmi come implementarlo? Come in, i passaggi corretti da seguire. Grazie.
Anjan Baradwaj

Ha funzionato bene per me. Testato dopo sia sendRedirect(...)e forward().
Hal50000

5

* .jsp in Url Pattern non funzionerà se inoltri una pagina. Prova a includere anche il tuo servlet .. questo renderà la tua applicazione sicura da questo problema con il pulsante Indietro.


2

Il modo più semplice per farlo senza disabilitare di nuovo il browser è aggiungere questo codice page_loadall'evento per la pagina a cui non si desidera che l'utente torni dopo essersi disconnesso:

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
Sebbene la tua risposta sia utile, pubblica la risposta che si riferisce al linguaggio di programmazione scelto dall'OP. La tua soluzione C # non aiuterà nel progetto Java EE dell'OP.
Buhake Sindi

0

Puoi provare a dire al browser di non memorizzare nella cache la home page (utilizzando le intestazioni appropriate: Expires, Cache-Control, Pragma). Ma non è garantito che funzioni. Quello che puoi fare è effettuare una chiamata ajax al server al caricamento della pagina per verificare se l'utente è loggato e, in caso contrario, reindirizzare.


13
Ma se una mente malvagia disabilita JavaScript, questo non funziona e vedrà comunque la pagina.
acme

0

Il modo corretto per farlo è aggiungere il file

Vary: Cookie

intestazione su pagine protette. Quando l'utente si disconnette, cancella il cookie di sessione. Quindi, quando tornano indietro dopo la disconnessione, la cache del browser perderà. Questo ha anche il vantaggio di non sconfiggere completamente il caching.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.