SSR と SPA
サーバ側 Cookie セッション(SSR)か、Bearer トークン(SPA+API)か。CORS・脆弱性の向き・失効・デプロイ形まで、違いはログイン情報の置き場から派生する
SSR と SPA の本当の分かれ目は、ログイン情報(トークン)の置き場です。サーバに預けるのが SSR、ブラウザが持つのが SPA で、違いはすべてここから派生します。
- SSR はトークンを隔離 — CSRF は枯れた対策で防げる
- SPA は XSS でトークンごと盗まれると被害が重い
- 選ぶ基準は安全の優劣よりクライアント構成
SSR と SPA、本当の分かれ目はどこ?
Web アプリの作り方は、サーバが HTML を組み立てて返す SSR と、ブラウザの JavaScript が画面を組み立てて別建ての API を呼ぶ SPA に大きく分かれます。画面の描き方の違いに見えますが、両者を分けている急所は別の場所にあります。
ログイン情報はどこに置く?(Cookie か Bearer か)
各ステップ・参加者・分岐をクリックすると、その仕組みの説明がここに表示されます。
この図をテキストで読む
シーケンス図「ログイン情報はどこに置く? ― Cookie(SSR)か Bearer(SPA)か」。参加者4人、ステップ10個。 【参加者】(左から右) - ブラウザ: 現場のPC・端末 - SSRサーバ: BFF も兼ねる - 認証基盤: Cognito 等 - API・DB: 業務データ 【流れ】(上から下へ) ── ① SSR(Cookieセッション / BFF)= トークンはサーバが預かる ── 1. ブラウザ → SSRサーバ: ログインしたい 2. SSRサーバ → 認証基盤: OIDC(認可コード+PKCE)で認証 3. 認証基盤 → SSRサーバ: トークンを発行(サーバが保管)(応答) 4. SSRサーバ → ブラウザ: httpOnly Cookie だけ返す(JSから読めない)(応答) 5. ブラウザ → SSRサーバ: 以後のアクセス(Cookieを自動付与) 6. SSRサーバ → API・DB: サーバ保管トークンで問い合わせ ── ② SPA+API(Bearerトークン)= トークンはブラウザのJSが持つ ── 7. ブラウザ → 認証基盤: PKCE(publicクライアント)で認証 8. 認証基盤 → ブラウザ: トークンがブラウザ(JS)に着地(応答) 9. ブラウザ → API・DB: Authorization: Bearer で直接呼ぶ 10. API・DB → ブラウザ: JWTを検証して結果を返す(CORS必須)(応答)
SSR と SPA を見くらべる(早見表)
各セルをクリックすると、その意味や詳しい説明がここに表示されます。
この図をテキストで読む
比較表。2列 × 9行。 【列】 1. SSR(Cookie / BFF)(サーバ側セッション) 2. SPA+API(Bearer)(ブラウザ側トークン) 【比較】(観点ごとに) ■ 資格情報の置き場 - SSR(Cookie / BFF): サーバが保管 / ブラウザは httpOnly Cookie だけ - SPA+API(Bearer): ブラウザのJSが保持 / Authorization: Bearer で送る ■ 認証の主体 - SSR(Cookie / BFF): サーバ(confidential) / 秘密あり・トークンはサーバへ - SPA+API(Bearer): ブラウザ(public / PKCE) / 秘密なし・トークンはブラウザへ ■ CORS - SSR(Cookie / BFF): 不要(同一オリジン) / ブラウザは自社サーバとだけ話す - SPA+API(Bearer): 必須(別オリジン) / プリフライト/credentials の設定 ■ 主な脆弱性 - SSR(Cookie / BFF): CSRF(対策で防げる) / XSSでもトークン窃取は不可 - SPA+API(Bearer): XSSでトークン窃取 / CSRFは基本なし ■ 失効(revoke) - SSR(Cookie / BFF): 即時 / サーバセッションを捨てるだけ - SPA+API(Bearer): 困難 / 短命+refresh回転 or denylist ■ トークン更新の責任 - SSR(Cookie / BFF): サーバが透過的に / クライアントは無知でよい - SPA+API(Bearer): ブラウザが自前で / 401インターセプタ等 ■ デプロイ形 - SSR(Cookie / BFF): 常駐サーバ1本+静的 / 1デプロイ・同一オリジン - SPA+API(Bearer): 静的SPA+別API / 2デプロイ・2オリジン ■ マルチクライアント - SSR(Cookie / BFF): web=Cookie / モバイル=Bearer / BFFがBearerの顔も兼ねられる - SPA+API(Bearer): 最初からBearerで均一 / 多クライアントで割に合う ■ 複雑さの所在 - SSR(Cookie / BFF): サーバ1か所に集約 / 総量は小・自分の管理下 - SPA+API(Bearer): 部品が分散 / 各部品を独立に置換できる 【観点】 - SSR を見る: SSR(Cookie / BFF) - SPA を見る: SPA+API(Bearer)
選ぶ基準は『誰が使うか』
安全さの優劣より、クライアント構成で選ぶのが実務的です。利用者が主に1つの Web アプリなら SSR/BFF が素直で、モバイルや外部にも同じ API を配るなら SPA+API が割に合います。どちらを選んでも、その方式の弱点を確実に塞ぐことが本番です。
押さえておきたい用語
- Cookie セッション
- 本人確認のしるしをサーバ側で保管し、ブラウザには預かり番号入りの Cookie だけを渡す方式。
- Bearer トークン / JWT
- 『持っていれば通れる』トークンをヘッダに載せて送る方式。JWT は署名付きの自己完結型で、サーバに状態を持たず検証できる。
- BFF(Backend for Frontend)
- フロント専用の裏方サーバ。認証基盤との配線やトークン保管を肩代わりし、ブラウザにトークンを出さない。
- httpOnly Cookie
- JavaScript から読めない印をつけた Cookie。XSS が起きても中身のトークンを盗み出せない。
- CSRF
- ログイン済みの利用者に意図しない操作をさせる攻撃。SameSite Cookie などの枯れた対策でほぼ防げる。
- CORS
- ブラウザが別ドメインの API を呼ぶときに必要な仕組み。別オリジンの SPA+API では必須で、設定ミスが弱点になりやすい。
ここから先へ
この解説とつながりのあるページ