web-dev-qa-db-ja.com

Cookieヘッダーの文字列を期限切れにします

簡単な質問だと思いますが、答えが見つからないようです。

次のような応答ヘッダーでブラウザに送信されるCookieクラスを使用してJavaサーブレットにCookieを書き込んでいます。

Set-Cookie: test=somevalue; Domain=.mydomain.org; Expires=Thu, 06-Jan-2011 18:45:20 GMT; Path=/

これは、サーブレット2.5APIのCookieクラスを介して行っています。この文字列の最後に「HTTPOnly」を追加する必要がありますが、これはサーブレット2.5APIではサポートされていません。問題ありません。文字列を手動で作成し、最後に「HTTPOnly」を追加します...

ただし、そうする際に遭遇した課題は、最初に「Expires」ヘッダーをそこに設定するために、その文字列の「Expires」部分を作成する.setMaxAge(3600)を使用したことです。ただし、Cookieクラスを使用できないため、その「Expires」部分の値を作成する必要があります。

基本的に、「3600」を「2011年1月6日木曜日18:45:20 GMT」にフォーマットするにはどうすればよいですか?

注:DateFormatを使用して正しいパターンを理解できる可能性がありますが、それを行うためのより良い方法があることを望んでいました。別の考え:以前と同じようにCookieクラスを使用し、プログラムでCookieを対応するヘッダー文字列に変換してから、最後に「HTTPOnly」を追加します。しかし、Cookieオブジェクトを取得して、対応する文字列値に変換する方法を私は知りません。

オプションで、Cookieオブジェクトを取得して、プログラムで対応する文字列値に変換するにはどうすればよいですか?

ありがとう!

14
JasonStoltz

このようなもの :

Date expdate = new Date ();
expdate.setTime (expdate.getTime() + (3600 * 1000));
String cookieExpire = "expires=" + expdate.toGMTString();
...

..そしてtoGMTString()は非推奨になっているので

Date expdate= new Date();
expdate.setTime (expdate.getTime() + (3600 * 1000));
DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Java.util.Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String cookieExpire = "expires=" + df.format(expdate);
22
RealHowTo

Java 8は、適切な日付フォーマッターを提供するようになりました DateTimeFormatter.RFC_1123_DATE_TIME

OffsetDateTime oneHourFromNow 
        = OffsetDateTime.now(ZoneOffset.UTC)
        .plus(Duration.ofHours(1));

String cookieExpires 
        = DateTimeFormatter.RFC_1123_DATE_TIME
        .format(oneHourFromNow);

// E.g. "Tue, 8 Nov 2016 20:15:46 GMT"

この形式は、expires属性に有効です。 RFC6265§4.1.1 を参照してください。これは、形式をRFC1123日付として定義します。

expires-av        = "Expires=" sane-cookie-date
sane-cookie-date  = <rfc1123-date, defined in [RFC2616], Section 3.3.1>
11
kuporific

さて、この質問についてはあまり活動が見られないので、将来答えを探している人に助けを提供するために、これに答えようと思います。ただし、他の人が選択した場合にジャンプする機会を与えるために、開いたままにしておきます。

だから私が考えたいくつかのオプションがありました...

1)

Apache Commons HTTPClientプロジェクトには、私が機能することを期待していた「DateUtil」クラスがあります。 http://hc.Apache.org/httpclient-3.x/apidocs/org/Apache/commons/httpclient/util/DateUtil.html 。これにより、日付をいくつかの標準形式にフォーマットしてhttpヘッダーで日付を伝達するための便利な方法が提供されます...ただし、サーブレットコンテナによって返されるものと正確に一致するものはないようです。

2)

Apache Commonsには、そのプロジェクトにCookieクラスもあります。このクラスには、文字列を返す「toExternalForm」メソッドがあります。それを使って、いつものようにクッキーを作成し、「toExternalForm」を呼び出してから「HTTPOnly」を追加することができたのではないかと思いました。 http://hc.Apache.org/httpclient-3.x/apidocs/org/Apache/commons/httpclient/Cookie.html 。それはうまくいくかもしれませんが、私はわざわざ試しませんでした。

3)

最終的に、標準形式であるかどうかに関係なく、サーブレットコンテナが返すものと一致するパターンを使用することにしました。サーブレットコンテナが返すものであれば、機能するはずですよね?何故なの...

SimpleDateFormat COOKIE_EXPIRES_HEADER_FORMAT = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zzz");
COOKIE_EXPIRES_HEADER_FORMAT.setTimeZone(new SimpleTimeZone(0, "GMT"));
Date d = new Date();
d.setTime(d.getTime() + 3600 * 1000); //1 hour
String cookieLifeTime = COOKIE_EXPIRES_HEADER_FORMAT.format(d);
response.setHeader("Set-Cookie", "test=somevalue; Domain=.mydomain.org; Expires=" + cookieLifeTime + "; Path=/; HTTPOnly");
6
JasonStoltz

JasonStoltzによって与えられた最初の答えは正しいものです:

1)Apache Commons HTTPClientプロジェクトには、私が機能することを期待していた「DateUtil」クラスがあります。 http://hc.Apache.org/httpclient-3.x/apidocs/org/Apache/commons/httpclient/util/DateUtil.html 。これにより、日付をいくつかの標準形式にフォーマットしてhttpヘッダーで日付を伝達する便利な方法が提供されます...ただし、サーブレットコンテナによって返されるものと正確に一致するものはないようです。

DateTimeライブラリを使用して、将来の1時間(または任意の時間)の日付オブジェクトを取得してから、ApacheDateUtilクラスを使用します。 そのクラスはRFCに従って出力するので、サーブレットが「通常生成するもの」と一致しないことを心配する必要はありません-ブラウザはRFCを尊重します

コードは次のようになります。

// for one hour later (should probably use date libraries in general, this is somewhat awkward)
Date expiresDate = new Date(new Date().getTime() + 3600*1000); 
response.setHeader("Set-Cookie", "Expires=" + DateUtil.formatDate(expiresDate) + ";");
2
schimmy