サブドメインの異なるサービス間で cookie を共有する


https://www.nicovideo.jp  // ニコニコ動画
https://live.nicovideo.jp // ニコニコ生放送
https://ch.nicovideo.jp   // ニコニコチャンネル

例えば上記のように、異なるサブドメインにおいてもログインセッションなどのデータを共有したい場合があります。

セキュリティの都合上オリジン(<scheme>://<hostname>:<port>)の異なる場所と JavaScript 内でデータの送受信を行う場合はオリジン間リソース共有(CORS)の仕組みを利用する必要があります。

しかし、 CORS のような仕組みを信頼されうるサブドメインの違いだけで利用するのは面倒です。

今回は Cookie の仕様を用いて、データを共有出来るようにします。

要約

;domain=example.com オプションを付けること。

domain オプションがついていなければ、現在のオリジンでしか使えないクッキーとなります。

Cookie のドメイン指定を利用する

これは先ほど例に挙げたニコニコを含め、非常に多くのサービスで既に利用されている方法です。

クッキーには、 key=value の他にオプションを設定することが出来ます。

  • ;path=パス オリジン以下のパスを指定することで、そのパス以下のクッキーと認識させることが出来ます。デフォルトでは現在のパスが設定されます。
  • ;domain=ドメイン このクッキーが指し示すドメインを指定します。デフォルトでは現在のドメインが指定されます。後述。
  • ;max-age=寿命(秒) 設定されてからこの秒数を経過した場合、このクッキーは無効とされます。
  • ;expires=GMTString 形式の日付 設定した日付以降、このクッキーは無効とされます。 max-ageexpires も指定されなかった場合は、セッションが終了(タブが閉じられる)すると無効になります。
  • ;secure https 通信のときのみこのクッキーを送信出来ます。
  • ;samesite=(lax|strict) strict の場合は、同一オリジンからのリクエストのみクッキーを送信します。 lax の場合は、別オリジンの a タグや GET form などのリクエストでもクッキーを送信します。

ここで今回重要になってくるのが domain オプションの設定です。

domain

このオプションを設定しない場合は、同一のオリジンでのみ利用可能なクッキーとなります。

このオプションを設定した場合は、そのドメイン(例えば nicovideo.jp)と、そのサブドメイン(例えば live.nicovideo.jp)でも利用可能なクッキーとなります。

また、 nicovideo.jp のページ上で domain=google.com のように ホスト名が異なるクッキーを設定することは出来ません (設定しても無視されます)。

しかし、 www.nicovideo.jp のページ上で domain=nicovideo.jp というクッキーを設定することは可能です。そうした場合、そのクッキーは nicovideo.jp 内の どんなサブドメインからでもアクセスが可能 になります。

このように、 domain オプションを指定することによって、サブドメインが異なるサービスでもログインセッション情報などを気軽に共有することが可能です。逆に、指定がない場合はサブドメインが違えば共有出来ません。

以前は domain=.nicovideo.jp のように、プレフィックスにドットを置くことで「サブドメインを含めて利用可能」と明示することとする場合があったようですが、現在はプレフィックスにドットを置いても無視される仕様となっています。

※弊害

例えば開発環境なんかは https://dev.www.nicovideo.jp のようなドメインを使うことがあるのではないかと思います。しかし、先ほどのように domain=nicovideo.jp というクッキーがあった場合、開発環境でもそのクッキーを利用可能な状態になってしまいます。

なので、最低限環境ごとにクッキーの名前をわけられるようにして、開発環境と本番環境のクッキーが干渉しないような設計にしましょう。

参考資料