web-dev-qa-db-ja.com

空白のあるCookie値が引用符でクライアント側に届くのはなぜですか?

私はJavaに手を出し始めている.NET開発者です。

.NETでは、Cookieの値を空白を含む文字列に設定できます:new HttpCookie("myCookieName", "my value")-クライアント側(JavaScript)でその値を読み取ると、期待した値が得られます(私の価値)。

Javaサーブレット--new Cookie("myCookieName", "my value")で同じことを行うと、二重引用符を含む値( "my value")が得られます。

なぜ違いがあるのですか?私は何かが足りないのですか? Javaの世界では、人々はこれをどのように処理しますか?値をエンコードしてから、クライアント側でデコードしますか?

25
jdoe

Cookie#setValue() で説明されているように、次のいずれかの値でCookie値を設定すると、

バージョン0のCookieでは、値に空白、角かっこ、括弧、等号、コンマ、二重引用符、スラッシュ、疑問符、アットマーク、コロン、およびセミコロンを含めることはできません。空の値は、すべてのブラウザで同じように動作するとは限りません。

その場合、平均的なコンテナは、Cookieをデフォルトのバージョン0( Netscape仕様 )ではなくバージョン1( RFC 2109仕様 )に暗黙的に設定します。動作はサーブレットAPIによって指定されておらず、コンテナはそれを自由に実装できます(たとえば、IllegalArgumentExceptionをスローする場合があります)。私の知る限り、Tomcat、JBoss AS、Glassfishは、Cookieのバージョンを暗黙的に変更することに関してすべて同じように動作します。少なくともTomcatとJBossASの場合、これは このセキュリティ問題 の修正の結果です。

バージョン1のCookieは次のようになります。

name = "value with space"; Max-Age = 3600; Path = /; Version = 1

バージョン0と互換性のあるCookieは次のようになります。

name = value%20with%20spaces; Expires = Mon、29-Aug-2011 14:30:00 GMT; Path = /

(URLエンコードされた値はバージョン0で有効であることに注意してください)

重要な注意点は、Microsoft InternetExplorerはバージョン1のCookieをサポートしていないということです。現在のIE 11リリースではありません。Cookie値全体の一部である引用符を解釈し、それに応じて処理して返します。Max-Age属性をサポートしていません。それは完全に無視されるため、Cookieの有効期間はデフォルトでブラウザセッションになります。WebアプリのCookie処理をテストするためにIEを使用していたようです。

MSIEもサポートするには、バージョン0で無効な文字が含まれている可能性がある場合、Cookie値を自分でURLエンコードおよびURLデコードする必要があります。

Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
// ...

そして

String value = URLDecoder.decode(cookie.getValue(), "UTF-8"));
// ...

世界中のユーザー向けにバージョン1のCookieをサポートするには、MicrosoftがMSIEサポートの欠如を修正し、修正されたブラウザーが主流になるのを本当に待ちます。言い換えれば、それはagesを要します(更新:現在、5年以上後、それは決して起こらないようです) 。それまでの間、バージョン0と互換性のあるCookieを使用することをお勧めします。

43
BalusC

私の知る限り、スペースはCookieでエンコードする必要があります。ブラウザが異なれば、エンコードされていないCookieに対する反応も異なります。設定する前に、CookieをURLエンコードする必要があります。

String cookieval = "my value";
String cookieenc = URLEncoder.encode(cookieval, "UTF-8");
res.addCookie(new Cookie("myCookieName", cookieenc));

ASP.NETはエンコードを自動的に行います。Javaは自分で行う必要があります。表示されている引用符は、ユーザーエージェントによって追加されていると思われます。

5
Tomalak

おそらく、JavaがCookieをエンコードする方法と関係があります。新しいCookieで setVersion(1) を呼び出して、それが機能するかどうかを確認することをお勧めします。

3
Randolpho

SetVersion(0)を使用してみてください。

HttpCookie cookie = new HttpCookie("name", "multi Word value");
System.out.println(cookie.toString());

プリント:

name = "いくつかの単語の値"

しかし、設定後

cookie.setVersion(0);
System.out.println(cookie.toString());

プリント:

name =いくつかの単語の値

エンコーディングも良い考えですが、値の周りの引用符は独立した問題のように見えます。

0
Talos