Sprachunabhängige Cookie-Encoding / Decoding-Standards

8

Ich habe Schwierigkeiten, herauszufinden, welcher Standard (oder gibt es einen?) für das Codieren / Decodieren von Cookie-Werten unabhängig von Backend-Plattformen.

RFC 2109 :

  

Der Wert ist für den Benutzeragenten undurchsichtig und kann alles sein, was der Ursprungsserver auswählen möchte, möglicherweise in einer vom Server ausgewählten druckbaren ASCII-Codierung. "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 überprüft.

Das klingt wie "Server ist der Chef" und entscheidet, was auch immer für die Codierung gilt. Dies macht es ziemlich schwierig, einen Cookie beispielsweise aus dem PHP-Backend zu setzen und ihn aus Python oder Java oder ähnlichem zu lesen, ohne eine manuelle Kodierung / Dekodierung auf beiden Seiten zu schreiben.

Nehmen wir an, 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 Pythons SimpleCookie -Klasse, für die codiert wird / dekodiert aus Oktalliteralen , obwohl viele sagen, dass oktale Literale werden in ECMA-262, strengem Modus, abgeschrieben. Wtf?

Also wird unser roher Cookie-Wert "/\"07051705051405 (*} 0705001705050017\"/"

Node.js:

Habe noch gar nicht getestet, aber ich rate nur, dass ein JavaScript-Backend es mit nativen encodeURIComponent und decodeURIComponent Funktionen, die hexadezimal Flucht / Unerledigungen?

PHP:

PHP wendet urlencode auf die Cookie-Werte an, die encodeURIComponent , aber nicht genau dasselbe.

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 , die nicht einmal in Anführungszeichen eingeschlossen ist.

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

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

    
kirpit 24.02.2013, 19:36
quelle

3 Antworten

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 ist, was RFC 2109 hier zu sagen versucht.

Das Konzept von Cookies in http ist dem im echten Leben ähnlich: Wenn Sie einem Club die Eintrittsgebühr bezahlen, 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 passiert das Gleiche. 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 tatsächlichen Daten den Server niemals verlassen und somit vertrauenswürdig sind. Alles, was auf der Client-Seite gespeichert ist, kann manipuliert werden und sollte nicht vertrauenswürdig sein.

Bearbeiten: Nachdem ich deinen Kommentar gelesen und deine Frage noch einmal gelesen habe, glaube ich, dass ich deine Situation endlich verstanden habe und warum du eher an der eigentlichen Codierung des Cookies interessiert bist als wenn Sie es nur Ihrer Programmiersprache überlassen: 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 dafür, wie Daten in einem Cookie gespeichert werden . Der Standard besagt nur, dass ein Browser das Cookie genau so zurücksendet, wie es empfangen wurde . Das verwendete Kodierungsschema ist das, was Ihre Programmiersprache für geeignet hält.

Wenn wir auf das Beispiel aus dem wirklichen Leben zurückkommen, haben Sie jetzt zwei Türsteher, 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 ein eigenes standardisiertes Codierungsschema in allen verwendeten Sprachen erstellen. Möglicherweise müssen Sie Routinen auf niedrigerer Ebene verwenden, z. B. PHP header() anstelle von Routinen höherer Ebene, z. B. start_session() , um dies zu erreichen.

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

    
Hazzit 05.03.2013 20:11
quelle
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 dies, um andere Zeichensätze zu unterstützen, aber ich weiß nicht, wie weit es unterstützt wird.

    
ykaganovich 06.03.2013 00:00
quelle
0

Ich bevorzuge es, in UTF8 zu codieren und mit base64-Codierung zu umbrechen. Es ist schnell, allgegenwärtig und wird niemals Ihre Daten an beiden Enden verfälschen.

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

ENCODE: nativeString - & gt; utfEncode () - & gt; base64Encode ()

DECODE: base64Decode () - & gt; utfDecode () - & gt; nativeString

Fast jede Sprache, die ich kenne, unterstützt dies heutzutage. Sie können nach einem universellen single-function encode suchen, aber ich irr auf der Seite der Vorsicht und wähle den zweistufigen Ansatz ... vor allem mit fremden Zeichensätzen.

    
pestilence669 06.03.2013 07:21
quelle