【ITニュース解説】Setting cross site cookies for same root domain, diff subdomain
2025年09月18日に「Reddit /r/programming」が公開したITニュース「Setting cross site cookies for same root domain, diff subdomain」について初心者にもわかりやすく解説しています。
ITニュース概要
異なるサブドメインでWebサービスを展開する際、フロントエンドで設定した認証クッキーをAPI側が読み取れず、ユーザー認証に問題が生じている。CORS関連の制限下で、APIがユーザーを検証するための技術的な解決策が求められている。
ITニュース解説
Webアプリケーションの開発において、異なるWebサイトやサービス間でユーザーの認証情報を共有することはよくある課題の一つだ。今回のニュース記事では、api.xyz.com というAPI(バックエンド)と ui.xyz.com というフロントエンドが同じルートドメイン xyz.com の異なるサブドメインで運用されている状況で、ユーザー認証に使うJWT(JSON Web Token)という情報をクッキーに保存する際に直面した問題について語られている。
この投稿者が抱える問題は、APIサーバーがJWTをクッキーとして設定しても、それがフロントエンドである ui.xyz.com から利用できない、あるいはAPI側 (api.xyz.com) でユーザーを認証するために必要なトークンが取得できないというものだ。これは、Webブラウザがクッキーを扱う際のセキュリティ上の仕組みと、ドメインの概念を理解することで明確になる。
Webアプリケーションは通常、ユーザーインターフェースを提供する「フロントエンド」と、データの処理やビジネスロジックを実行する「バックエンド」に分かれている。ユーザーがWebサイトにログインすると、そのユーザーが誰であるかを識別するための認証情報(例えばJWT)が発行される。この情報は、多くの場合、Webブラウザの「クッキー」という仕組みを使って保存される。クッキーは、Webサイトがブラウザに「この情報を保存して、次にこのサイトにアクセスするときに私に送り返してね」と指示することで機能する小さなデータのことだ。これにより、ユーザーはサイトを訪れるたびに再ログインする必要がなくなる。
ここで重要なのが、「ドメイン」と「オリジン」の概念だ。xyz.com は「ルートドメイン」と呼ばれ、ui.xyz.com や api.xyz.com はその「サブドメイン」にあたる。Webブラウザは、セキュリティのために「同一オリジンポリシー (Same-Origin Policy)」という非常に厳格なルールを設けている。これは、あるWebページが、異なる「オリジン」のリソースにアクセスするのを制限するものだ。オリジンは、プロトコル(例: https://)、ホスト名(例: ui.xyz.com)、そしてポート番号の三つの組み合わせで定義される。ui.xyz.com と api.xyz.com は、同じルートドメインを持つが、ホスト名が異なるため、Webブラウザから見ればこれらは「異なるオリジン」として扱われる。
クッキーには「Domain」という属性があり、このクッキーがどのドメインに対して送信されるべきかを指定できる。通常、クッキーはそれを設定したドメインに対してのみ送信されるようになっている。つまり、api.xyz.com で設定されたクッキーは、デフォルトでは api.xyz.com にアクセスするときにしかブラウザから送信されない。ui.xyz.com にアクセスしても、そのクッキーは送信されないのだ。サブドメイン間でクッキーを共有したい場合、クッキーのDomain属性をルートドメイン(例えば .xyz.com)に設定する必要がある。このように設定すると、xyz.com とその全てのサブドメイン(ui.xyz.com、api.xyz.com など)に対してそのクッキーが送信されるようになるため、サブドメイン間の認証情報の共有が可能になる。
しかし、この投稿者は、「xyz.com ルートドメインには既に別の何かがホストされていて、Domain属性を .xyz.com に設定できない」という大きな制約を抱えている。これが、最も直接的で一般的なクッキー共有の解決策を妨げている主要な原因だ。さらに、「api.ui.xyz.com のようなネストされたサブドメインも、共有ホスティングプロバイダーの制限で作成できない」という制約も、システム設計の柔軟性をさらに奪っている。投稿者が「CORS(Cross-Origin Resource Sharing)の件」と述べているが、CORSは異なるオリジン間のリソース共有を許可するための仕組みであり、クッキーの共有問題とは直接的に異なるが、根底にある「異なるオリジン」という概念で関連性がある。
この状況下で、考えられる解決策はいくつかあるが、それぞれに注意点やトレードオフが伴う。
一つのアプローチは、JWTをクッキーではなく、Webブラウザの「ローカルストレージ (localStorage)」や「セッションストレージ (sessionStorage)」に保存する方法だ。これらのストレージは同一オリジンポリシーに従うため、ui.xyz.com で保存された情報を api.xyz.com から直接読み取ることはできない。しかし、フロントエンドがAPI (api.xyz.com) にリクエストを送信する際に、ローカルストレージからJWTを読み出し、リクエストヘッダーに手動で含めて送信することは可能だ。ただし、この方法はセキュリティ上のリスクを高める可能性がある。特に、クロスサイトスクリプティング(XSS)攻撃に対して脆弱になる。クッキーに HttpOnly というフラグを設定すれば、JavaScriptからのアクセスを防ぎ、XSS攻撃の影響を軽減できるが、ローカルストレージに保存されたデータはJavaScriptから常にアクセス可能であるため、XSS攻撃を受けた場合、JWTが容易に窃取される恐れがある。
別の解決策として、「バックエンドプロキシ」の利用が考えられる。これは、ui.xyz.com からのAPIリクエストを、ui.xyz.com と同じオリジンで動作するプロキシサーバーを経由させる方法だ。例えば、ui.xyz.com/api というパスへのリクエストをプロキシサーバーが受け取り、それを内部的に api.xyz.com へ転送する。ブラウザから見れば、全てのAPIリクエストが ui.xyz.com という同一オリジンに対して行われているように見えるため、クッキーも同一オリジンで管理しやすくなる。しかし、この方法はプロキシサーバーの導入と管理が必要になり、インフラ構成の複雑さが増す可能性がある。
根本的な解決策としては、認証フロー自体を見直すことも視野に入れる必要があるかもしれない。OAuth 2.0やOpenID Connectのような標準プロトコルを利用した、より高度なシングルサインオン(SSO)ソリューションの導入も考えられる。これらは、認証プロセスを特定のドメインに縛られない形で設計することを可能にするが、システムの変更規模が大きく、より専門的な知識と実装コストが必要となる。
投稿者が数日間も行き詰まっているのは、これらの代替策がいずれも何らかのセキュリティリスク、実装の複雑さ、あるいは追加コストを伴うためだろう。この問題は、Webアプリケーションの認証とセキュリティ、特にドメイン管理とクッキーの挙動に関する基本的な理解が、いかに重要であるかを示している。システムエンジニアを目指す初心者にとっては、同一オリジンポリシー、クッキーのDomain属性、そしてこれらの制約がある中でいかに安全かつ効率的な認証メカニズムを設計するかが、学ぶべき重要な課題となる。実際の開発現場では、このような制約の中で最適な解決策を見つける能力が常に求められるからだ。