― 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の認証フローの基盤技術

