ブラウザ毎の Cookie の path に対する挙動の違いによって、検証しているアプリに色々とバグっぽい挙動が出てきたので、あらためて Cookie における挙動をまとめてみます。
検証内容
- セットするCookie の path 属性に
/path
、あるいは/path/
を指定した Web アプリを作成 - 個々のブラウザで、次のパスにアクセスし、Cookie が送信されるかどうかを確認
/path
/patha
/path/
/path/a
このへんのアプリだったら Perl とかでサクっと作った方が早いので、PSGI アプリとして実装しました。 だいたい以下のようなかんじです。
#!/usr/bin/env perl use Plack::Builder; use Plack::Request; use Plack::Middleware::Session::Cookie; my $app = sub { my $env = shift; my $req = Plack::Request->new($env); my $cookies = $req->cookies; my $res = $req->new_response(200); $res->body(%{$cookies}? 'cookie sent' : 'no cookie'); $res->finalize; }; builder { enable 'Session', state => Plack::Session::State::Cookie->new(path => '/path'); # path は '/path' と '/path/' の双方を試した $app; }
まずは結果を
○ が「Cookie が送信された」、- が「Cookie は送信されなかった」ことを表現しています。 挙動が大きく違っていたのは IE 11 だったんですが、家に Windows がないので、調べることができませんでした。
後述しますが、Chrome と Safari は、RFC 6265 に沿っています。
FIrefox もほぼ沿っているんですが、Cookie の Path の末尾が /
の場合に、RFC 6265 と挙動が異なるように見えます。
path=/path
ブラウザ | /path |
/patha |
/path/ |
/path/a |
---|---|---|---|---|
Chrome 61.0.3163.100 | ○ | - | ○ | ○ |
Firefox 56.0.2 | ○ | - | ○ | ○ |
Safari 11.0 (12604.1.38.1.7) | ○ | - | ○ | ○ |
path=/path/
ブラウザ | /path |
/patha |
/path/ |
/path/a |
---|---|---|---|---|
Chrome 61.0.3163.100 | - | - | ○ | ○ |
Firefox 56.0.2 | ○ | - | ○ | ○ |
Safari 11.0 (12604.1.38.1.7) | - | - | ○ | ○ |
RFC はどうなのか
Cookie について定義しているのは RFC 6265 ですが、この 5.1.4. Paths and Path-Match に、 path をどのようにしてマッチさせるべきなのかの定義があります。
詳細は見て頂ければ良いのですが、まず最初に、cookie の path と比較する対象として、uri-path
を定義します。
これは、リクエスト URI のうち、ホスト名の後の /
からクエリパラメータの ?
より前の最後の /
の前までと url-path
とされています。
- /hoge/fuga/piyo
なら /hoge/fuga
- /hoge
なら /
これに対し、cookie の path が以下のどれかを満たすなら、そのときに cookie が送出されます。 読めばなるほどなぁと分かるんですが、これを日本語で簡潔に説明すると難しいので、読んで頂いた方が誤解がないと思います。
o The cookie-path and the request-path are identical. o The cookie-path is a prefix of the request-path, and the last character of the cookie-path is %x2F ("/"). o The cookie-path is a prefix of the request-path, and the first character of the request-path that is not included in the cookie- path is a %x2F ("/") character.
参考文献
- 徳丸浩の日記: 10月 2011
- RFC 6265 - HTTP State Management Mechanism
- ブラウザごとの cookie path の挙動の違い - Please Sleep
- 2013 年の記事ですが、こちらの解析の方が私のよりもずっと充実していました。
- Safari は、大きくその挙動を変えたようです。
- どさにっき