コンテンツにスキップ

BFF パターンで OAuth トークンをブラウザの外に出す

要約

SPA でアクセストークン・リフレッシュトークンを localStorage / sessionStorage / メモリに置くと XSS で盗まれる。BFF(Backend for Frontend)パターンでトークンを BFF サーバー側に保持し、ブラウザには HttpOnly Cookie のみを渡すことで根本的に解決できる。

問題の構造

【従来の SPA】
ブラウザ → 認可サーバー → アクセストークンをブラウザで保持
                              ↑ XSS があれば JS から盗める

BFF パターンの認証フロー

ブラウザ (SPA)
    ↓ 認証開始リクエスト
BFF サーバー(confidential client として動作)
    ↓ 認可コードフロー(PKCE 付き)
認可サーバー
    ↓ アクセストークン・リフレッシュトークン
BFF サーバー(トークンを内部で保管)
    ↓ HttpOnly Cookie のみ返す
ブラウザ (SPA) ← JS からトークンにアクセス不可

必要なセキュリティ設定

  • Cookie: HttpOnly + Secure + SameSite=Strict + __Host- プレフィックス
  • CSRF: SameSite だけに頼らず CORS + Origin ヘッダー検証や CSRF トークンを併用
  • BFF の転送先ホストを allowlist で検証(SSRF 防止)

コンポーネント分割(API 駆動 BFF)

コンポーネント 役割
OAuth Agent 認証処理 API(認可コードフロー実行・トークン管理)
OAuth Proxy API ゲートウェイプラグイン。Cookie を Authorization ヘッダーに変換して転送

注意点

  • PKCE と BFF は代替でなく併用する
  • ログアウト設計が複雑になる(BFF のセッション + IDP のセッションの両方を破棄)
  • BFF を挟む分、インフラ管理コストが増える