Neu: Das englische Ruby on Rails 4.0 Buch.

8.1. Cookies

Mit einem Cookie kann man auf dem System des Webbrowsers Informationen in Form von Strings als Key-Value-Pair (Schlüssel-Wert-Paar) speichern, die der Webserver vorher an diesen Browser geschickt hat. Die Informationen werden später im HTTP-Header wieder vom Browser an den Server geschickt. Ein Cookie wird dabei (bei entsprechender Konfiguration) auf dem Browsersystem weder durch einen Neustart des Browsers noch durch einen Neustart des ganzen Systems gelöscht. Natürlich kann der Benutzer des Browsers den Cookie manuell löschen.

Wichtig

Ein Browser muss keine Cookies akzeptieren und er muss sie auch nicht speichern. Allerdings leben wir in einer Welt, in der fast jede Seite Cookies benutzt. Deshalb haben die meisten User die Cookie-Funktionalität aktiviert. Mehr Informationen zum Thema Cookie finden Sie auf Wikipedia unter http://de.wikipedia.org/wiki/HTTP-Cookie.

Tipp

Ein Cookie kann nicht beliebig lang sein (maximal 4 kB). Man muss sich dabei auch immer vor Augen halten, dass die Informationen der gespeicherten Cookies immer vom Browser an den Server geschickt werden. Er sollte nur zur Speicherung von kleinen Datenmengen (z. B. einer Kundennummer) eingesetzt werden, um den Overhead im Protokoll nicht zu groß werden zu lassen.
Rails bietet uns einen Hash namens cookies[], den wir transparent benutzen können. Um den technischen Kleinkram kümmert sich dann Rails automatisch im Hintergrund.
Um die Arbeitsweise mit Cookies zu veranschaulichen, bauen wir uns eine Rails-Applikation, die auf einer Seite einen Cookie setzt, auf einer anderen Seite diesen Cookie ausliest und den Inhalt anzeigt und einer dritten Seite, die den Cookie wieder löscht.
MacBook:~ xyz$ rails new cookie_jar
[...]
MacBook:~ xyz$ cd cookie_jar
MacBook:cookie_jar xyz$ rails generate controller Home set_cookies show_cookies delete_cookies
[...]
MacBook:cookie_jar xyz$
Die Controller-Datei app/controllers/home_controller.rb befüllen wir wie folgt:
class HomeController < ApplicationController
  
  def set_cookies
    cookies[:user_name]   = "Horst Meier" 
    cookies[:kundenummer] = "1234567890" 
  end
  
  def show_cookies
    @user_name    = cookies[:user_name]
    @kundennummer = cookies[:kundenummer]
  end
  
  def delete_cookies
    cookies.delete :user_name
    cookies.delete :kundenummer
  end
  
end
Und die View-Datei app/views/home/show_cookies.html.erb so:
<h1>Home#show_cookies</h1>
<p>Find me in app/views/home/show_cookies.html.erb</p>

<table>
 <tr><td>User-Name:</td><td><%= @user_name %></td></tr>
 <tr><td>Kundennummer:</td><td><%= @kundennummer %></td></tr>
</table>
Starten Sie den Rails-Server mit rails server und öffnen Sie die URL http://0.0.0.0:3000/home/show_cookies in Ihrem Browser. Sie werden keine Werte angezeigt bekommen. Öffnen Sie jetzt die URL http://0.0.0.0:3000/home/set_cookies und danach wieder http://0.0.0.0:3000/home/show_cookies. Jetzt bekommen Sie die Werte angezeigt, die wir in der Methode set_cookies gesetzt haben.
Mit dem Aufruf der Seite http://0.0.0.0:3000/home/delete_cookies können Sie die Cookies wieder löschen.

Wichtig

Die so gesetzten Cookies "leben" auf dem Browser so lange, bis der Browser ganz geschlossen wird.

Warnung

Der Inhalt eines normal gesetzten Cookies im Browser ist für den User problemlos und einfach zu lesen. Er wird nicht verschlüsselt und sollte deshalb keine Passwörter oder ähnliche Daten enthalten. Es ist auch nicht ratsam, einen Warenkorb in einem unsignierten (siehe „Signierte Cookies (signed cookies)“) Cookie zu speichern, da sonst der User selber Preise in diesem Warenkorb ändern könnte.

Permanente Cookies (permanent cookies)

Cookies werden normalerweise gesetzt, um der Applikation eine Möglichkeit zu geben, User bei späteren Besuchen wiederzuerkennen oder Einkaufskörbe zu speichern. Zwischen diesen Besuchen der Website kann viel Zeit ins Land gehen und der Browser auch mal vom User geschlossen werden. Um Cookies länger als für die aktuelle Browser-Sitzung zu speichern, gibt es die permanent-Methode. Unser obiges Beispiel können wir in der app/controllers/home_controller.rb um diese Methode erweitern:
class HomeController < ApplicationController
  
  def set_cookies
    cookies.permanent[:user_name]   = "Horst Meier" 
    cookies.permanent[:kundenummer] = "1234567890" 
  end
  
  def show_cookies
    @user_name    = cookies[:user_name]
    @kundennummer = cookies[:kundenummer]
  end
  
  def delete_cookies
    cookies.delete :user_name
    cookies.delete :kundenummer
  end
  
  def debug_cookies
  end
  
end

Wichtig

„permanent“ heißt hier nicht wirklich permanent. Man kann einen Cookie nicht permanent setzen. Ein Cookie braucht beim Setzen immer einen „gültig-bis“-Stempel, den der Browser dazu benutzen kann, alte Cookies automatisch zu löschen. Mit der permanent-Methode wird dieser Wert auf das heutige Datum in 20 Jahren gesetzt. Das ist praktisch mit permanent gleichzusetzen.

Signierte Cookies (signed cookies)

Bei normal gesetzten Cookies hat man auf Applikationsseite keine Möglichkeit herauszufinden, ob der User der Applikation den Cookie eigenhändig geändert hat. Das kann schnell zu einem Sicherheitsproblem führen, den Inhalt eines Cookies im Browser zu ändern, ist kein Zauberwerk. Die Lösung ist eine Signierung der Cookies mit einem nur uns bekannten Key. Dieser Key wird bei einem rails new automatisch per Zufallsgenerator erzeugt und liegt in der Datei config/initializers/secret_token.rb:
# Be sure to restart your server when you modify this file.

# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
CookieJar::Application.config.secret_token = '85ec33910d4d57f3d3c69cb8fef20f158f68a219a76db71280779454a523330874fc4e42c7e62ecb25b8e4f5fcce1dcad88c7dcc9671a9922f675d770270a25a'

Warnung

Sollten Sie Ihre Rails-Applikation irgendwann mal neu aufsetzen und wieder mit einem frischen Rails-Projekt anfangen, so ist es hilfreich, diesen Key in die neue Rails-Applikation zu übertragen. Sonst können Sie die vorher gesetzten Cookies nicht mehr benutzen!
Um Cookies zu signieren, gibt es die Methode signed. Diese muss beim Schreiben und Lesen des Cookies benutzt werden. Unser obiges Beispiel können wir in der app/controllers/home_controller.rb um diese Methode erweitern:
class HomeController < ApplicationController
  
  def set_cookies
    cookies.permanent.signed[:user_name]   = "Horst Meier" 
    cookies.permanent.signed[:kundenummer] = "1234567890" 
  end

  def show_cookies
    @user_name    = cookies.signed[:user_name]
    @kundennummer = cookies.signed[:kundenummer]
  end

  def delete_cookies
    cookies.delete :user_name
    cookies.delete :kundenummer
  end

  def debug_cookies
  end
  
end
Der Inhalt des Cookies wird jetzt bei jedem Setzen verschlüsselt abgespeichert. Der Name des Cookies ist weiterhin im Klartext für den User lesbar. Der Wert aber nicht mehr.

Autor

Stefan Wintermeyer