スポンサーリンク

ポップアップ完了を親ページへ安全に伝える方法

JavaScript
スポンサーリンク
本ページにはプロモーションが含まれています。
スポンサーリンク

― postMessage と window.addEventListener(‘message’) の実践解説 ―

Webアプリケーションを作っていると、次のような要件に出会います。

  • ポップアップウィンドウで認証や決済を行う
  • 完了したら元の画面に戻したい
  • しかも安全に状態を同期したい

OAuthログイン、決済画面、本人確認フローなど、現代のWebでは非常に一般的なパターンです。

このときに使われる標準技術が postMessage API です。

本記事では、

  • window.addEventListener('message') の正体
  • なぜ必要なのか
  • 安全な実装方法
  • 実務での設計パターン

を体系的に解説します。

1. postMessageとは何か

postMessageは一言でいうと:

別ウィンドウ・別タブ・iframe間で安全にデータを送受信するブラウザ標準API

です。

通常ブラウザには Same Origin Policy(同一生成元ポリシー) があり、

  • 別ドメインのページ
  • 別タブのページ
  • iframe内のページ

には JavaScriptから直接アクセスできません

しかし、

「安全に“データだけ”を渡す仕組み」

として用意されているのが postMessage です。

2. 基本構造(送信側と受信側)

送信側(ポップアップなど)

window.opener.postMessage(
  { type: "DONE" },
  "https://example.com"
);

ポイント

  • window.opener
    → このウィンドウを開いた親ページ
  • 第2引数
    送信先ドメインを明示(重要なセキュリティ)

受信側(親ページ)

window.addEventListener("message", function (event) {
  console.log(event.data);
});

ここで 別ウィンドウからの通知を受け取れます。

3. messageイベントで受け取れる情報

event には重要な情報が入っています。

event.data

送信されたデータ本体

{ type: "DONE" }

event.origin(最重要)

送信元のドメイン

例:

https://example.com

event.source

送信元ウィンドウオブジェクト(通常はあまり使わない)

4. なぜ origin チェックが必須なのか

もし origin を確認しないと、
他サイトから偽の完了通知を送れてしまいます。

攻撃例

window.postMessage(
  { type: "DONE", redirect: "https://evil.com" },
  "*"
);

→ 親ページがそのまま遷移
オープンリダイレクト攻撃

正しい防御コード

window.addEventListener("message", function (ev) {
  if (ev.origin !== "https://example.com") return;
  if (!ev.data || ev.data.type !== "DONE") return;

  location.href = ev.data.redirect;
});

これで:

  • 他ドメイン ❌ ブロック
  • 正規ドメイン ⭕ 許可

となります。

5. なぜURLパラメータではダメなのか

ポップアップ完了後に

  • window.location
  • クエリパラメータ
  • 手動で戻る

などでも実装できます。

しかし問題があります。

UXの問題

  • ユーザーが閉じ忘れる
  • タイミングがズレる
  • 元ページ状態と同期できない

postMessageを使う利点

  • 完了した瞬間に通知
  • 親ページが即反応
  • 状態同期が正確
  • ページ遷移不要

現代Webの標準解法

6. 実務での典型フロー

親ページ
  │
  ├─ window.open()
  │
  ▼
ポップアップ(認証・決済)
  │
  ├─ 完了
  │
  ├─ window.opener.postMessage()
  │
  ▼
親ページが message を受信
  │
  └─ 画面更新 or 遷移

7. 実は世界中で使われている

この仕組みは特別なものではありません。

  • Google OAuth
  • Stripe / PayPal 決済
  • LINEログイン
  • SSO全般

すべて postMessageベースです。

つまり:

Web認証フローの世界標準

8. 安全な実装チェックリスト

必須

  • origin を必ず検証
  • type フィールドでイベント種別を判定
  • targetOrigin"*" にしない

推奨

  • opener が存在するか確認
  • redirect URL を自ドメインに限定
  • 完了後に window.close()

9. 設計の本質

この仕組みの本当の価値は:

サーバ状態の変化をUIに正確に反映すること

です。

  • 認証完了
  • 決済成功
  • 本人確認OK

などの重要イベント
安全に親画面へ伝達できます。


まとめ

window.addEventListener('message') とは

別ウィンドウからの安全な完了通知を受け取る仕組み


できること

  • 認証・決済・SSOの完了通知
  • ポップアップ → 親ページの状態同期
  • UXを壊さない非同期フロー

重要ポイント

  • origin検証は必須
  • postMessageは世界標準
  • 現代Webの認証フローの基盤技術
タイトルとURLをコピーしました