# Session zerstören



## frageUMantwort (22. Jul 2011)

Hallo miteinander.

Ich möchte gerne eine Session zerstören. Dafür habe ich ein kleines Beispiel erstellt:

// index.jsp

```
<%-- 
    Document   : index
    Created on : 21.07.2011, 10:29:38
    Author     : Administrator
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Beispiel</title>
    </head>
    <body>
        <a href="/BeispielSession/test">Session setzen</a><br>
    </body>
</html>
```

// Session wird gesetzt ( aufruf siehe index.jsp )

```
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Test extends HttpServlet {
   
    public static HttpSession session = null;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            response.addHeader("Pragma:", "no-cache");
            response.addHeader("Pragma:", "no-store");

            if(session == null){
                session = request.getSession(true);
            }
 
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet Test </title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet Test "+ session.getId() +" </h1>");
            out.println("<a href=\"/BeispielSession/remove\">remove session</a><br>");
            out.println("</body>");
            out.println("</html>");
            
        } finally { 
            out.close();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

}
```

und das Servlet Remove:

```
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class Remove extends HttpServlet {
   

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

            response.addHeader("Pragma:", "no-cache");
            response.addHeader("Pragma:", "no-store");
            response.addHeader("Expires:", new Date().toGMTString());


            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet Remove</title>");  
            out.println("</head>");
            out.println("<body>");

            if(Test.session != null)
                out.println("<h1>Remove Session: " + Test.session.getId() + "</h1>");
            else
                out.println("<h1>Session zerstört</h1>");

            out.println("</body>");
            out.println("</html>");
            Test.session.invalidate();
            Test.session = null;

        } finally { 
            out.close();
        }
    } 

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 
}
```

Gut, nun wenn die Session gesetzt wird (im TestServlet) und dann anschliessend im RemoveServlet die Session zerstöre. Wird sie auch Erfolgreich "zerstört" allerdings kann der User z. B im Browser die Seite zuvor wieder auswähle ( zrück gehen ). Ich gehe mal stark davon aus der der Browser dann auf den Cache zugreift und deshalb mir nicht anzeigt das die Session zerstört ist. Sobald man die Seite aktualisiert oder wieder auf die Verlinkung zu RemoveServlet geht, wird auch korrekt angezeigt, dass die Session zerstört wird. Weil ja wieder eine Anfrage geschickt wird. 
Meine frage ist nun: 

Wie kann ich dafür sorgen, dass er nicht auf dem Cache zugreift, wenn der User im Browser wieder zurückgeht?

Oder wie macht man es in der Praxis? z. B bei Logout, das der User nicht zurück gehen kann und das Formular zuvor doch noch sehen kann? 

Dieses Beispiel soll nur zum Verständniss sein, damit ich dann die Möglichkeit kenne wie man so eine Session (die über Servlets gesetzt wurde) zerstört. 

Wird in der Praxis dann mehr auf JSP gesetzt und dort die Session gesetzt? 

Gruß


----------



## Tente (22. Jul 2011)

Du kannst den Browser nicht dazu zwingen, wenn er in der History zurück geht einen erneuten Request an deinen Server zu schicken, um die Session-Validität zu prüfen. Daher kannst du den Inhalt natürlich sehen. Jede Aktion die er dann jedoch ausführen würde, dürfte dann jedoch auf den Hammer laufen. Gleiches hier im Forum. Meld dich ab und geh im Browser auf "Zurück". Du bist dann wieder scheinbar angemeldet. Aber wenn du dann eine Aktion ausführst bekommt der Server mit, dass du keine valide Session hast und führt nichts aus.

Da du in der Praxis, wenn du mit JSP oder JSF arbeitest eh tendenziell weniger mit eigenen Servlets arbeitest, bietet es sich dann an über JSP oder ManagedBeans die Sessions zu zerstören. Die einfachere Methode ist hierbei eine JSP anzulegen, die aus der Session invalidate() aufruft.


----------



## ARadauer (22. Jul 2011)

Mhn nein das hast du falsch verstanden..


```
public class Test extends HttpServlet {
   
    public static HttpSession session = null;
```
Das darfst du nicht tun. Da würden sich die Benutzer gegenseitig die Session überschreiben. Du musst bei jedem Request die Session aus dem Request hohlen. Da kannst du dann werte rein schreiben. Ausloggen würde so funktionieren...
request.getSession().invalidate();


----------



## frageUMantwort (22. Jul 2011)

Ok, also gibt es keine Möglichkeit mit JSP oder Servlets. Mich wundert es ein wenig, da es ja z. B bei gmx.de oder anderen Seite klappt das wunderbar. Was ja nicht heißen muss das die damit Arbeiten. Dort wird anscheinend mit Timeouts gearbeitet nur meine Kentnisse sind da *noch* beschränkt. 



> Du kannst den Browser nicht dazu zwingen, wenn er in der History zurück geht einen erneuten Request an deinen Server zu schicken ...


Ja das mit der erneuten request war mir bewusst, habs leider vergessen zu erwähnen. Aber kann man das Historyback nicht verhindert bzw dem Browser sagen das er die Seite nicht im Cache speichern soll?!? 

Oder gibt es evtl. noch anderen Möglichkeiten? (siehe gmx/web/google uvm.)



> Aber wenn du dann eine Aktion ausführst bekommt der Server mit das du keine valide Session hast und führt nichts aus.


Jep, das war mir auch bewusst


----------



## frageUMantwort (22. Jul 2011)

ARadauer hat gesagt.:


> Mhn nein das hast du falsch verstanden..
> 
> 
> ```
> ...



Ah, danke für den Hinweis, sehr dumm von mir. 
Mit 
	
	
	
	





```
request.getSession().invalidate();
```
 zerstöre ich die Session aber das historyback kann der User trotzdem machen. Gut wenn er dann eine Aktion auf der Seite macht wird sie nicht ausgeführt.


----------



## SlaterB (22. Jul 2011)

> Du kannst den Browser nicht dazu zwingen, wenn er in der History zurück geht einen erneuten Request an deinen Server zu schicken, um die Session-Validität zu prüfen.

vielleicht aber bitten?
So, You Don't Want To Cache, Huh?


----------



## frageUMantwort (22. Jul 2011)

Danke SlaterB. 

Das schaut sehr viel versprechend aus. Habe es im Ansatz im Servlet schon versucht :

```
response.addHeader("Pragma:", "no-cache");
            response.addHeader("Pragma:", "no-store");
```

Aber wie gesagt im Ansatz versucht  
Werde euch Berichten sobald ich das mal hinbekommen habe.


----------



## ARadauer (22. Jul 2011)

Noch als Anmerkung. Das Servlet gibt es nur einmal! 5.000 Benutzer mit 100 gleichzeitigen Requests. Aber das Objekt ist nur einmal da. Achtung man darf nicht mal normale Klassenvariablen im Servlet benutzen (ausser man weiß was man da tut)


----------



## maki (22. Jul 2011)

Speziell beim Backbutton verhalten sich manche Browser etwas seltsam was die "bitte nicht cachen" Sache betrifft.

Zwingen kann man den Browser und das Netzwerk schon, zB. ein Token an die URL hängen dass sich mit jedem Request ändert, damit ist die URL immer anders und damit wird im Cache zu der URL nie etwas gefunden, ist aber unschön imho.

Man kann sich natürlich auch etwas in JavaScript schrieben das auf den Backbutton reagiert und dann eine Meldung ausgibt und verhindert dass der Backbutton wirklich ausgeführt wird.
Ist halt eine Frage wie man die User erzieht, wirklich sauber gelöst hat das ganze Back/History/Navigationszeug imho GWT.

frageUMantwort, bist du sicher dass die Session jemals null ist?
Dürfte m.E. niemals der Falls sein, es sollte eine neue erzeugt werden wenn die alte invalidiert wird.


----------



## SlaterB (22. Jul 2011)

> zB. ein Token an die URL hängen dass sich mit jedem Request ändert, damit ist die URL immer anders 

naja, 'Browser back' ist doch in der Regel der Button in der Menüzeile, nicht ein komplett neuer Link auf der Webseite der nur zufällig zu exakt derselben Seite führt


----------



## maki (22. Jul 2011)

Ja, für den Backbutton kann man nur JavaScript nutzen, oder eben sowas wie GWT.

Persönlich habe ich bis GWT nur in Projekten gearbeitet, in denen der Back Button verboten war.


----------



## frageUMantwort (22. Jul 2011)

ARadauer hat gesagt.:


> Noch als Anmerkung. Das Servlet gibt es nur einmal! 5.000 Benutzer mit 100 gleichzeitigen Requests. Aber das Objekt ist nur einmal da. Achtung man darf nicht mal normale Klassenvariablen im Servlet benutzen (ausser man weiß was man da tut)




Danke für den Hinweis. Wenn, dann würde ich nur lokale Variablen verwenden. Hoffe dies wäre dann ein besserer Ansatz? Wobei man nach meinen bisherigen Wissenstand sowenig wie möglich in Servelts macht. Aber ich bin auch seit einer Woche erst dabei mir J2EE anzueignen. 

@maki 
Stimmt da findet man einiges an Scripts, danke für den Hinweis. 
Ok, also Session sollte also niemals null sein, danke


----------



## maki (23. Jul 2011)

> Ok, also Session sollte also niemals null sein, danke


Nö, meine Frage war schlicht ob beid dir die Session jemals null ist, imho nicht möglich, lasse mich aber gerne eines besseren belehren.


----------

