2013-02-24 14 views
8

Ich habe Schwierigkeiten herauszufinden, was ist der Standard (oder gibt es irgendwelche?) Für die Codierung/Decodierung von Cookie-Werten unabhängig von Backend-Plattformen.Sprache agnostische Cookies Codierung/Decodierung Standards

Nach RFC 2109:

Der Wert ist undurchlässig für die Agenten Benutzer und kann alles sein, der Ursprungs-Server, möglicherweise in einem Server-ausgewählte druckbaren ASCII-Kodierung gesendet wählt. "Opaque" bedeutet, dass der Inhalt nur für den Ursprungsserver von Interesse und relevant ist. Der Inhalt kann tatsächlich von jedem gelesen werden, der den Set-Cookie-Header untersucht.

was klingt wie "Server ist der Chef" und es entscheidet, was die Codierung anwenden wird. Dies macht es ziemlich schwierig, ein Cookie beispielsweise aus dem PHP-Backend zu setzen und es aus Python oder Java oder ähnlichem zu lesen, ohne eine manuelle Codierung/Decodierung auf beiden Seiten zu schreiben.

Sagen wir, wir haben einen Wert, der codiert werden muss. Russisch /"печенье (*} значения"/ bedeutet "Cookie-Wert" mit einigen zusätzlichen nicht-alphanumerischen Zeichen darin.

Python:

Fast jeder WSGI Server macht das gleiche und verwendet SimpleCookie Klasse Python, das codiert zu/von octal literals decodiert, obwohl viele sagen, dass octal literals are depreciated in ECMA-262, Strict-Modus. WTF?

Also, unsere raw Cookie-Wert wird "/\"\320\277\320\265\321\207\320\265\320\275\321\214\320\265 (*} \320\267\320\275\320\260\321\207\320\265\320\275\320\270\321\217\"/"

Node.js:

Haben nicht getestet, aber ich vermute, nur ein JavaScript-Backend mit nativer encodeURIComponent und decodeURIComponent Funktionen tun würde das verwenden hexadecimal entkommen/unescaping?

PHP:

PHP gilt urlencode auf die Cookie-Werte, die encodeURIComponent ähnlich, aber nicht genau das gleiche.

So wird der Rohwert; %2F%22%D0%BF%D0%B5%D1%87%D0%B5%D0%BD%D1%8C%D0%B5+%28%2A%7D+%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F%22%2F das ist nicht einmal mit Anführungszeichen umwickelt.

Jedoch; wenn der JavaScript value Variable, die den PHP-codierten Wert oben hat, gibt decodeURIComponent(value)/"печенье+(*}+значения"/ finden Sie unter "+" Zeichen anstelle von Leerzeichen ..

Wie ist die Situation in Java, Ruby, Perl und .NET? Welche Sprache (oder am nächsten) dem gewünschten Verhalten folgt. Gibt es dafür einen Standard für W3?

Antwort

4

Ich denke, Sie haben die Dinge hier ein wenig durcheinander gebracht. Die Kodierung des Servers spielt für den Client keine Rolle und sollte nicht. Das versucht RFC 2109 hier zu sagen.

Das Konzept von Cookies in http ist im echten Leben ähnlich: Nach der Zahlung der Eintrittsgebühr zu einem Club erhalten Sie einen Tintenstempel auf Ihrem Handgelenk. Dadurch können Sie den Club verlassen und wieder betreten, ohne erneut zu bezahlen. Alles, was Sie tun müssen, ist, Ihr Handgelenk dem Türsteher zu zeigen.In diesem Beispiel aus dem wirklichen Leben ist es dir egal, wie es aussieht, es könnte sogar unsichtbar sein bei normalem Licht - alles was wichtig ist ist, dass der Türsteher das Ding erkennt. Wenn du es abwaschen würdest, verlierst du das Privileg, in den Club zurückzukehren, ohne wieder zu zahlen.

In HTTP ist das gleiche passiert. Der Server setzt einen Cookie mit dem Browser. Wenn der Browser zum Server zurückkehrt (lesen Sie: die nächste HTTP-Anfrage), zeigt er das Cookie auf dem Server an. Der Server erkennt den Cookie und handelt entsprechend. Solch ein Cookie könnte etwas so einfaches wie ein "WasHereBefore" -Marker sein. Auch hier ist es nicht wichtig, dass der Browser versteht, was es ist. Wenn du dein Cookie löschst, wird der Server so tun, als ob er dich nie zuvor gesehen hätte, genau wie der Türsteher in diesem Club, wenn du diesen Tintenstempel weggespült hättest.

Heutzutage speichern viele Cookies nur eine wichtige Information: eine Sitzungskennung. Alles andere wird serverseitig gespeichert und dieser Sitzungskennung zugeordnet. Der Vorteil dieses Systems besteht darin, dass die eigentlichen Daten den Server niemals verlassen und somit vertrauenswürdig sind. Alles, was auf der Clientseite gespeichert ist, kann manipuliert werden und sollte nicht vertrauenswürdig sein.

Edit: Nachdem Sie Ihren Kommentar zu lesen und Ihre Frage zu lesen noch einmal, ich glaube, ich endlich verstanden, Ihre Situation, und warum Sie Interesse an dem tatsächlichen Codierung des Cookies, anstatt es einfach zu Programmiersprache zu verlassen: Wenn Sie zwei verschiedene Softwareumgebungen auf demselben Server haben (zB: Perl und PHP), möchten Sie vielleicht ein Cookie dekodieren, das von der anderen Sprache gesetzt wurde. Im obigen Beispiel muss PHP den Perl-Cookie decodieren oder umgekehrt.

Es gibt keinen Standard, wie Daten in einem Cookie gespeichert werden. Der Standard sagt nur, dass ein Browser das Cookie zurück senden wird genau wie es empfangen wurde. Das verwendete Kodierungsschema ist das, was Ihre Programmiersprache für geeignet hält.

Zurück zum realen Beispiel, haben Sie jetzt zwei Rausschmeißer, von denen einer Englisch, der andere Russisch spricht. Die beiden müssen sich auf eine Art von Tintenstempel einigen. Wahrscheinlich wird mindestens einer von ihnen die Sprache des anderen lernen.

Da das Browserverhalten standardisiert ist, können Sie entweder ein Sprachencodierungsschema in allen anderen auf Ihrem Server verwendeten Sprachen nachahmen oder einfach Ihr eigenes standardisiertes Codierungsschema in allen verwendeten Sprachen erstellen. Möglicherweise müssen Sie Routinen niedrigerer Ebene verwenden, z. B. PHP header() anstelle von höheren Routinen wie start_session(), um dies zu erreichen.

BTW: Auf dieselbe Weise entscheidet die serverseitige Programmiersprache, wie serverseitige Sitzungsdaten gespeichert werden. Sie können nicht auf CGI::Session von Perl zugreifen, indem Sie das $_SESSION Array von PHP verwenden.

+0

+1 für die unsichtbare Tinte! Obwohl Cookies sehr gut verwendet werden können, um strukturierte Daten zwischen Servern auf ein und derselben Domain zu teilen. – flup

+0

ja, gutes Beispiel. Ich würde gerne das Kopfgeld dazu geben, wenn es die Frage in ** fettem ** Teil beantwortet. wie auch immer, Cookies sollten unabhängig von der Art der Daten, die sie übertragen, plattformübergreifend gelesen werden können. traurig und Schmerz in den Arsch. – kirpit

+0

Ich glaube ich habe deine Frage endlich verstanden und meine Antwort entsprechend bearbeitet. – Hazzit

2

Unabhängig davon, ob der Cookie für den Client undurchsichtig ist, muss er dennoch der HTTP-Spezifikation entsprechen. rfc2616 gibt an, dass alle HTTP-Header ASCII (ISO-8859-1) sein sollten. rfc5987 erweitert das, um andere Zeichensätze zu unterstützen, aber ich weiß nicht, wie weit es unterstützt wird.

+0

ASCII ist eine Teilmenge (die untere Hälfte) von ISO-8859-1 – flup

+0

@FLUP, Sie haben Recht. Wenn ich das RFC richtig verstehe, erwartet es tatsächlich ASCII. – ykaganovich

0

Ich bevorzuge Codierung in UTF8 und wrap mit Base64-Codierung. Es ist schnell, allgegenwärtig und wird niemals Ihre Daten an beiden Enden verfälschen.

Sie müssen eine explizite Konvertierung in UTF8 sicherstellen, auch wenn Sie sie umbrechen. Andere Sprachen & Laufzeiten, während Unicode unterstützt, möglicherweise nicht Strings als UTF8 intern speichern ... wie viele Windows-APIs. Python 2.x, meiner Erfahrung nach, erhält Unicode-Strings selten ohne explizite Konvertierung.

ENCODE: nativeString -> utfEncode() -> Base64Encode()

DECODE: base64decode() -> utfDecode() -> nativeString

Fast jede Sprache, die ich kenne, in diesen Tagen unterstützt diese . Sie können nach einem universellen single-function encode suchen, aber ich irr auf der Seite der Vorsicht und wähle den zweistufigen Ansatz ... besonders bei fremden Zeichensätzen.