🍘

サードパーティー製Cookieをブロックしたらサイトが機能しなくなる原因と対策

に公開

はじめに

サードパーティー製Cookieと聞くと、「ユーザーの行動を追跡するやつ」とか「合法ウイルス」とか「パーティーの3次会で出てくるクッキー」とかいう印象を持つ方も多いと思う。しかし、システムの開発側としては必ずしも悪い目的で使うわけではないし、サードパーティー製Cookieがブロックされると正常に機能しないシステムも考えうる。本記事では、サードパーティー製CookieでWebサイトが機能しなくなる原因と、その対策について解説する。

問題提起

フロントエンドとバックエンドを別々で公開するAjax型のサイトを考えよう。例えば、APIを「api.example.com」、フロントエンドを「www.example.com」というホストで実装する場合を考える。ユーザーが「www.example.com」でログインボタンを押すと、フロントエンドは入力されたIDとパスワードを「api.example.com」に送信する。バックエンドはそれを検証し、正しければセッションIDを含んだCookieをブラウザに保存させる。

ここまではいいだろう。問題は、ログイン後にフロントエンドが再度「api.example.com」にデータを要求する場面である。ブラウザはリクエストと一緒に、以前保存したCookieを送信しようとする。しかし、ブラウザの設定でサードパーティー製Cookieをブロックするように設定してある場合、Cookieの送信は失敗する。なぜなら、ブラウザから見れば「www.example.com」というサイトから「api.example.com」という別のサイトへCookieが送られているためである。結果として、バックエンドはユーザーを認証できず、「未ログイン状態」として扱ってしまう。これが、サードパーティー製Cookieの制限によって、意図せず認証が機能しなくなるメカニズムである。

解決策

解決策1:リバースプロキシの使用

リバースプロキシを設定し、https://www.example.com/api/*へのリクエストをバックエンドサーバーへ、それ以外をフロントエンドサーバーに転送する方法。ブラウザから見れば、全てのリクエストが同じホストへの通信に見える。結果として、Cookieはサードパーティー製Cookieとして扱われないためブロックされない。

解決策2:そもそもCookieを使わない

「サードパーティー製CookieがブロックされるならCookie使わなきゃいいじゃん」という発想。以下の手順で認証を行う。

  1. フロントエンドからhttps://api.example.com/loginのようなリクエストを送信する。
  2. バックエンドは、IDとパスワードが正しいかなどを検証し、問題無ければトークンを返す。このとき、トークンはCookieではなくレスポンスボディに記載する。
  3. フロントエンドは、返ってきたトークンをlocalStorageなどに保存する。
  4. フロントエンドは、次回以降リクエストを送信する際、トークンを読み出してAuthorizationヘッダーに記載する。

なお、バックエンド側で適切にCORSを設定し、フロントエンドからレスポンスを読み込めるようにしていることが前提。

さいごに

個人的には、CookieのSameSite属性との相性の良さという理由から、解決策1の方が好み。

ちなみに筆者の好きなクッキーはカントリーマアムである。

Discussion