SSRでセッション管理が難しくなる理由とCookieの扱い
SSR(Server Side Rendering)はSEOや初期表示速度に有利ですが、実装を始めると多くの人が「ログイン周りだけ急に難しくなった」と感じます。原因はフレームワークではなく、ブラウザとサーバの境界の位置が変わることにあります。
SPAでは認証が複雑、SSRでは簡単、という印象を持たれがちですが、実際には逆の場面も多くあります。特にセッション管理はSSR特有の落とし穴が発生します。
まずCookieとセッションの関係を整理する
Webのログイン状態は、多くの場合Cookieによって維持されています。ログイン時、サーバはセッションIDを発行し、それをCookieとしてブラウザに保存させます。
Set-Cookie: SESSIONID=abc123; Path=/; HttpOnly
次回アクセス時、ブラウザは自動的にこのCookieを送信します。
Cookie: SESSIONID=abc123
サーバはこのIDを使ってユーザーを特定します。これが一般的なセッション認証です。
SPAのときは何が起きていたか
SPAでは、ブラウザがAPIを直接呼びます。つまり通信は常に「ブラウザ → APIサーバ」です。
このときCookieは自然に送信されます。ブラウザは同一オリジンのリクエストに対して、自動でCookieを付与するからです。開発者はCookieの存在を意識しなくてもログイン状態は維持されます。
SSRでは通信経路が変わる
SSRではブラウザが直接APIを呼びません。
- ブラウザ → SSRサーバ
- SSRサーバ → APIサーバ
ここが重要です。SSRサーバがAPIを呼ぶとき、その通信は「サーバ間通信」です。ブラウザではありません。
つまり、ブラウザに保存されたCookieはAPIサーバに届きません。
ここでログイン状態が消えたように見えます。
なぜログインできない現象が起きるのか
SSRでよく起きる現象があります。
- ブラウザでログイン済み
- API直接アクセスは成功
- SSRページだけ未ログイン扱い
原因は単純です。SSRサーバがAPIを呼ぶ際、ユーザーのCookieを転送していないからです。
SSRサーバから見れば、そのリクエストは「匿名ユーザーのサーバ通信」です。
解決方法:Cookieの転送(Forwarding)
SSRでは、受け取ったリクエストのCookieをAPIへ引き継ぐ必要があります。
const cookie = req.headers.cookie; await fetch(API_URL, { headers: { cookie } });
これを行うことで、APIサーバは同じセッションとして認識できます。
ただし、ここから設計が難しくなります。
HttpOnly Cookieとセキュリティ
セッションCookieは通常HttpOnlyに設定します。これはJavaScriptからCookieを読み取れないようにするセキュリティ対策です。XSSによるセッション窃取を防ぐためです。
ところがSSRではサーバがCookieを扱うため、アプリケーションコードがCookie転送を担うことになります。つまり、フレームワークの抽象化が破れ、HTTPの理解が必要になります。
別ドメインAPIの問題
さらに問題が複雑になるのが、APIサーバが別ドメインにある場合です。
- www.example.com(SSR)
- api.example.com(API)
Cookieにはドメイン制約があります。設定次第ではブラウザはCookieを送信しません。また、サーバ間通信ではブラウザのSameSiteポリシーが働きません。
結果として、ローカルでは動くのに本番でログインが維持されない現象が起きます。
セッションストアの問題
SSRはリクエストごとにレンダリングを行うため、同時アクセスが増えるとセッション参照が急増します。
もしメモリセッションを使っていると、次の問題が起きます。
- スケールアウトでログインが消える
- コンテナ再起動で全員ログアウト
- 負荷分散でセッション不一致
そのためRedisなどの共有セッションストアが必要になる場合が多いです。
よくある誤解:JWTなら解決する?
JWTを使えばセッション管理が不要になると考えられがちですが、SSRでは単純ではありません。
JWTをlocalStorageに保存すると、サーバは取得できません。結果としてSSRでユーザー情報を取得できなくなります。
CookieにJWTを入れれば解決しますが、それは結局「Cookieセッション」と同じ問題領域に戻ります。
実務上の注意点
SSRでログイン周りを実装するとき、次の確認が重要です。
- CookieはサーバからAPIへ転送されているか
- SameSite設定は適切か
- セッションストアは共有化されているか
特に開発環境では動いて本番で壊れるケースが多く、ドメイン設定が原因であることがよくあります。
まとめ
SSRでセッション管理が難しくなる理由は、認証方式の問題ではなく通信経路の変化です。ブラウザが直接APIを呼ばなくなり、サーバが代理通信を行うことでCookieの扱いを開発者が担うことになります。
SSRは表示の責務をサーバに移しますが、それと同時に「ブラウザが自動でやっていたこと」もサーバ側で再現する必要が出てきます。ログイン機構はその代表例です。
SSRを導入するときは、レンダリング方式だけでなく、認証とセッションの流れを最初に設計しておくと後戻りが少なくなります。