Java で、Cookie の値を取得方法を調べていたのですが、キー、Value は取得できるとして、有効期限の値が取得できないのができるのかよくわからず、実際にプログラムを書いて試してみました。 結果を以下に記載します。
前提
以下の環境で実施しています。
-
OS
% sw_vers ProductName: Mac OS X ProductVersion: 10.13.4 BuildVersion: 17E202
-
Java
% java -version java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
-
Dropwizard の version
<dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-core</artifactId> <version>1.1.2</version> </dependency>
-
使用ブラウザ
Chrome バージョン: 66.0.3359.181(Official Build) (64 ビット)
結論
結果として、サーバ側では、expires、max-age の値は取得できませんでした。
サーバ側で、
String rawCookie = httpRequest.getHeader("Cookie");
検証用プログラム
以下 Resource クラスと、Application クラスを作成して、localhost でアプリケーションを起動し、Cookie を設定して、Resource クラスの戻り値で取得状況を確認しました。
* CookieResource
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
@Path("cookies")
@Produces(MediaType.APPLICATION_JSON)
public class CookieResource {
@GET
public String toString(@Context HttpServletRequest httpRequest) {
javax.servlet.http.Cookie[] cookies = httpRequest.getCookies();
StringBuilder sb = new StringBuilder();
if (cookies != null) {
for (Cookie cookie : cookies) {
sb.append(encodeCookie(cookie));
sb.append("\n");
sb.append("Cookie#toString() " + cookie.toString());
sb.append("\n");
sb.append("---------------");
sb.append("\n");
}
}
String rawCookie = httpRequest.getHeader("Cookie");
sb.append("rawCookie#" + rawCookie);
return sb.toString();
}
/**
* Encode a cookie as per RFC 2109. The resulting string can be used
* as the value for a <code>Set-Cookie</code> header.
*
* @param cookie The cookie to encode.
* @return A string following RFC 2109.
*/
public static String encodeCookie(Cookie cookie) {
StringBuffer buf = new StringBuffer(cookie.getName());
buf.append("=");
buf.append(cookie.getValue());
if (cookie.getComment() != null) {
buf.append("; Comment=\"");
buf.append(cookie.getComment());
buf.append("\"");
}
if (cookie.getDomain() != null) {
buf.append("; Domain=\"");
buf.append(cookie.getDomain());
buf.append("\"");
}
long age = cookie.getMaxAge();
if (cookie.getMaxAge() >= 0) {
buf.append("; Max-Age=\"");
buf.append(cookie.getMaxAge());
buf.append("\"");
}
if (cookie.getPath() != null) {
buf.append("; Path=\"");
buf.append(cookie.getPath());
buf.append("\"");
}
if (cookie.getSecure()) {
buf.append("; Secure");
}
if (cookie.getVersion() > 0) {
buf.append("; Version=\"");
buf.append(cookie.getVersion());
buf.append("\"");
}
return (buf.toString());
}
}
- WebApplication.java
import io.dropwizard.Application; import io.dropwizard.Configuration; import io.dropwizard.setup.Environment; import xyz.monotalk.festivals4partypeople.web.dropwizard.resources.CookieResource; public class WebApplication extends Application<Configuration> { public static void main(String[] args) throws Exception { new WebApplication().run(args); } @Override public String getName() { return "WebApplication"; } @Override public void run(Configuration t, Environment e) throws Exception { // Resourceを追加 e.jersey().register(new CookieResource()); } }
検証結果
JavaScript で cookie を設定し、Web サービスにアクセスして、Cookie の取得状況を確認します。
キー値、Value のみを設定する
-
JavaScript
document.cookie = 'data=test';
-
Cookie の取得状況
max-age のない場合は、Cookie は session Cookie になります。data=test Cookie#toString() javax.servlet.http.Cookie@7bb02735 --------------- rawCookie#data=test
キー値、Value、max-age を設定する
-
JavaScript
document.cookie = 'data=test; max-age=1000000';
-
Cookie の取得状況
data=test Cookie#toString() javax.servlet.http.Cookie@13b5d6bc --------------- rawCookie#data=test
キー値、Value、max-age を設定する。 max-age は 1
-
Javascript
期限切れの場合の動作の検証です。
document.cookie = 'data=test; max-age=1';
-
Cookie の取得状況
キー値、Value が取得できなくなりました。
rawCookie#null
キー値、Value、expires を設定する。
-
Javascript
document.cookie = "data=test; expires=Thu, 01 Feb 2019 00:00:00 GMT";
-
Cookie の取得状況
data=test Cookie#toString() javax.servlet.http.Cookie@4e287944 --------------- rawCookie#data=test
キー値、Value、expires を設定する。 expires は過去日付
-
Javascript
document.cookie = "data=test; expires=Thu, 01 Feb 2017 00:00:00 GMT";
-
Cookie の取得状況
rawCookie#null
矛盾する、max-age、 expires を設定する
-
Javascript
document.cookie = "data=test; max-age=10000000, expires=Thu, 01 Feb 2019 00:00:00 GMT";
-
Cookie の取得状況
取得できたので、どちらかが効いているようです。
data=test Cookie#toString() javax.servlet.http.Cookie@353f71e4 --------------- rawCookie#data=test
max-age、 expires の優先順位の確認
-
Javascript max-age を短く設定
document.cookie = "data=test; max-age=3, expires=Thu, 01 Feb 2019 00:00:00 GMT";
-
Cookie の取得状況
rawCookie#null
-
Javascript expires を短く設定
document.cookie = "data=test; max-age=1000000, expires=Wed, 06 Jun 2018 01:08:50 GMT";
-
Cookie の取得状況
max-age のほうが優先順位が高いです。
data=test Cookie#toString() javax.servlet.http.Cookie@33bbf21b --------------- rawCookie#data=test
Expires vs max-age, which one takes priority if both are declared in a HTTP response? - Stack Overflow を見る限り、RFC で優先順位が定められているようです。
参考
以下、Cookie 関連を調べていて参考になった記事になります。
* RFC 6265 — HTTP State Management Mechanism (日本語訳)
* M-Fr Net Miscellany Cookie
* Apache TomcatとHTTPクッキーにまつわる騒動 - @int128
* Why Max-Age
cookie attribute is not used instead of a hairy Expires
attribute · Issue #421 · expressjs/session · GitHub
* java - Expires string in cookie header - Stack Overflow
* Cookieのexpireの扱いがブラウザによってちょっと異なる件 - mikanmarusanのブログ
* Cookie の仕様とセキュリティ
* 解決編!!Google Chrome Cookie expires(有効期限)バグ – 真夜中に奔る
* document.cookie - Web API インターフェイス | MDN
* クッキーの使用方法 | JavaScript プログラミング解説
* Learn how HTTP Cookies work
javax.servlet.http.Cookie
の JavaDoc を見る限りは、特にそれらしき記載はないので、勘違いしていました。
Cookie#getMaxAge()
は、サーバ側で設定した Cookie の存続期間 を取得するものかと思いました。
以上です。
コメント