Der Server kann den Client veranlassen, diese Information eine bestimmte Zeit lang zu speichern. Betritt der Client die Seite des Anbieters, schickt er dem Server den Cookie als Kennung. Dieser kann anhand der Cookie-Kennung die Sitzung erkennen, sofern er die Information gesichert hat. Name und Technologie der Cookies wurden von Netscape geprägt, als die Firma noch den Browser-Markt revolutionierte. Mittlerweile kümmert sich die HTTP Working Group der Internet Engineering Task Force (IETF) um die Weiterentwicklung.
Das Wort »Cookie« wird gerne mit Keksen assoziiert, was aber nicht beabsichtigt ist. Informatiker kennen den Begriff und meinen damit einfach nur kleine Informationseinheiten. Mehr Informationen rund um Cookies hat David Whalen auf seiner Seite http://www.cookiecentral.com/ gesammelt.
Cookies erzeugen und setzen
Cookies werden für den Benutzer durch die Klasse Cookie verwaltet. Sie bietet Methoden zur Bearbeitung der Informationen, die der Cookie speichert. Damit wir auf der Clientseite Cookies setzen können, müssen wir zunächst ein Cookie-Objekt erzeugen. Dazu bietet die Klasse genau einen Konstruktor mit zwei Parametern an, die dem Cookie einen Namen und einen Wert geben. Der Name muss nach RFC 2109 geformt sein, das heißt vereinfacht aus Buchstaben und Ziffern. Nun muss der Cookie beim Client gesetzt werden. Dies führt die Methode addCookie() auf dem HttpServletResponse-Objekt durch:
Cookie cookie = new Cookie( "key", "value" ); response.addCookie( cookie );
Da es mehrere Einträge geben kann, darf die Methode auch mehrmals aufgerufen werden.
interface javax.servlet.http.HttpServletResponse extends ServletResponse
- public void addCookie( Cookie cookie )
Fügt der Antwort einen Cookie-Header zu.
Cookies vom Servlet einlesen
Bei jeder weiteren Kommunikation mit einem Server werden die mit der Server-URL assoziierten Cookie-Daten automatisch mitgeschickt. Um sie zu erfragen, bemühen wir die Methode getCookies() des HttpServletRequest-Objekts. Der Rückgabewert der Methode ist ein Feld von Cookie-Objekten. Jeder Cookie bietet als Objektmethode getName() und getValue() an, um an die Schlüssel-Werte-Paare zu gelangen. Wenn die getCookies()-Methode null liefert, so war noch kein Cookie angelegt, und wir müssen darauf reagieren.
<%@ page import="java.util.*" %> <% String myCookieName = "visited"; Cookie[] cookies = request.getCookies(); if ( cookies == null ) out.println( "Kein Cookie gesetzt!" ); else { boolean visited = false; for ( int i = 0; i < cookies.length; i++ ) { String cookieName = cookies[i].getName(); if ( cookieName.equals(myCookieName) ) visited = true; %> Cookie "<%= cookieName %>" hat den Wert "<%= cookies[i].getValue() %>" <br> <% } if ( !visited ) { Cookie visCookie = new Cookie( myCookieName, new java.util.Date().toString() ); response.addCookie( visCookie ); out.println( "Cookie gesetzt" ); } } %>
Bekommt der Server eine Anforderung vom Client, kennt der Client natürlich die Server-Adresse. Er schaut in seinem Cookie-Speicher nach, ob mit diesem Server ein Cookie assoziiert ist. Dann schickt er diesen automatisch in einem speziellen Cookie-Feld mit, sodass der Server diesen Wert auslesen kann. Cookies sind für andere Server nicht sichtbar, sodass sie keine direkte Sicherheitslücke darstellen.
Cookie-Status ändern
Im Cookie werden neben einem Namen und dem damit verbundenen Wert noch weitere Informationen gespeichert. Die folgende Aufzählung zeigt die Zugriffsmethoden für Cookies:
class javax.servlet.http.Cookie
implements java.lang.Cloneable
- void setComment( String purpose )
- String getComment()
Eine zusätzliche Beschreibung für einen Cookie, der nicht von jedem Browser unterstützt wird (beispielsweise von Netscape). Bei der Abfragemethode bekommen wir null, falls dem Cookie kein Kommentar zugewiesen wurde. - setDomain( String pattern )
- String getDomain()
Der Gültigkeitsbereich eines Cookies. Der Domänenname beginnt mit einem Punkt (etwa .kuchenfuerulli.com) und gilt dann für alle direkten Rechner dieser DNS-Adresse, also etwa www.kuchenfuerulli.com, aber nicht a.b.kuchenfuerulli.com. - int getMaxAge()
- setMaxAge() legt fest, wie lange der Cookie existieren soll (in Sekunden). Ist der Wert negativ, wird der Cookie nicht gespeichert, sondern nach der Sitzung, also beim Schließen des Browsers, entfernt. getMaxAge() liefert die Lebensdauer eines Cookies, wobei die oben getätigten Aussagen auch hier zutreffen.
- void setPath( String uri )
- public String getPath()
Der Pfad gibt den Ort für den Client an, an dem der Cookie sichtbar ist. Die Sichtbarkeit gilt für das angegebene Verzeichnis und alle Unterverzeichnisse. Zusätzliche Informationen sind in RFC 2109 abgelegt. - void setSecure( boolean flag )
- public boolean getSecure()
Mit einer sicheren Verbindung lassen sich Cookies nur über ein sicheres Protokoll wie HTTPS oder SSL übertragen. setSecure(true) sendet den Cookie daher nur, wenn ein sicheres Protokoll verwendet wird. getSecure() liefert false, wenn der Browser den Cookie durch ein beliebiges Protokoll senden kann. - void setName( String name )
- String getName()
Der Name des Cookies, der nach der Erzeugung nicht mehr geändert werden kann. - void setValue( String newValue )
- String getValue()
Jeder Cookie speichert einen Wert, der mit setValue() neu gesetzt werden kann, sofern der Cookie existiert. Bei einem binären Wert müssen wir selbstständig eine ASCII-Kodierung finden, zum Beispiel eine BASE64-Kodierung. Mit Cookies der Version 0 sind die Zeichen › ‹, ›(‹, ›)‹, ›[‹, ›]‹, ›=‹, ›,‹, ›’‹, ›"‹, ›\‹, ›?‹, ›@‹, ›:‹, ›;‹ nicht zugelassen. Nicht gesetzte Werte können unterschiedliche Rückgaben des Browsers provozieren. - int getVersion()
- void setVersion( int v )
Die Version des Cookies, wie in RFC 2109 beschrieben. Version 0 hält sich an die Originalspezifikation von Netscape. Die Version 1 wird in RFC 2109 beschrieben; die Variante ist noch etwas experimentell.
Langlebige Cookies
Für Cookies, die länger als eine Sitzung halten sollen, lässt sich mit setMaxAge() eine Zeit setzen, zu der sie gültig sein sollen. Eine praktische Klasse ist MaxAgeCookie, die im parametrisierten Konstruktor das Alter auf die Höchstzahl von einem Jahr setzt. Dies müssen aber nicht alle Browser so implementieren.
import javax.servlet.http.*; public class MaxAgeCookie extends Cookie { public MaxAgeCookie( String name, String value ) { super( name, value ); setMaxAge( 60*60*24*365 ); } }