クロスドメインpostMessageまたはブラウザーが標準をサポートする方法

クラウドストレージをバックアップスクリプトに固定する場合、さまざまなクラウドAPIで使用するためにOAuth 2認証を使用する必要がありました。 原則として、認証自体に問題はありませんでしたが、問題はわずかに予期しない場所で発生しました。



ソフトウェアを使用する視聴者を考えると、古代のブラウザーのサポートを放棄することが決定され、HTML5を使用する現代のブラウザーのすべてが強化されました。



しかし、そこには...



異なるブラウザーによるpostMessageの解釈



クロスドメイン(異なるドメインのページの場合)が判明したため、postMessageを使用したブラウザーウィンドウ/タブ間の通信は、ChromeとFirefoxでのみ可能です(Chrome 30およびFirefox 25でテスト済み)。



IEでは、postMessageはframe / iframe(IE 11を含む)を使用している場合にのみ機能します。



Operaは予想外に驚きました。 バージョン12では、すべて正常に動作します。 ただし、Chromeと同じエンジンで作成されたOpera 17では、動作が異なります。 ドメインが異なる場合、postMessageはフレーム/ iframeでのみ機能し、個別のウィンドウ/タブでは機能しません。 ドメイン、より正確にはオリジン(つまり、プロトコル+ドメイン+ポート)が同じ場合、フレーム間およびウィンドウ/タブ間でメッセージが機能します。



すべてのブラウザがフレーム間のクロスドメイン通信をサポートしている場合、アプリケーションのiframeですぐに認証ウィンドウを開いてみませんか? しかし、ここでは注意深いX-Frame-Optionsが時流になります-ほとんどすべてのOAuthサーバーで、フレーム内の認証ページを開くことは禁止されています。



プロキシフレーム



怖い名前にもかかわらず、これはアプリケーションのサイトからダウンロードされた通常のiframeであり、そのタスクはOperaとIEの制限により直接転送できないため、受信したトークンをアプリケーションウィンドウに転送することです。



さまざまなオプションを試した後、トークンを取得するための次の非常に簡単なソリューションに決めました。



便宜上、次の定義を使用します。

  1. アプリケーション (Webアプリケーションは、事前に知られていないユーザーのドメインにあります)
  2. プロキシフレーム (アプリケーションのiframeに埋め込まれたアプリケーションサーバーにある中間フレーム)
  3. アプリケーションサイト(OAuth認証後にユーザーがリダイレクトされるサイト)
  4. OAuthサーバー (アクセスするサーバー)


合計で、3つのドメインを使用します。domain1-ユーザーアプリケーションのある場所、domain2-プロキシフレームとアプリケーションサイト、domain3-OAuthサーバー。



トークンを取得する手順は次のとおりです。

  1. プロキシフレームはアプリケーションページに埋め込まれます。





  2. プロキシフレームにあるボタンをクリックすると、OAuthサーバー認証ページが新しいウィンドウ/タブで開きます。





  3. ユーザーの同意後、OAuthサーバーはユーザーをアプリケーションウェブサイトに送信し、リクエストパラメーターに認証コードを含めます。
  4. アプリケーションサイトは、OAuthサーバーに対してPOSTリクエストを行い、認証コードとアプリケーションパスワードを、アクセス用のトークンおよび/または更新用のトークンと交換します。




  5. 受信したトークンはテキストフィールドに挿入されます(自動的にコピーできない場合)。 その後、トークンはlocation.hashの変更を使用してプロキシフレームに送信されます(プロキシフレームとアプリケーションサイトのプロトコル、ドメイン、ポートが同じであるため、これはすべてのブラウザーで機能します)。 実際、location.hashの使用が必要なのはIE(IE 11を含む)のみです。postMessageはその異なるウィンドウでは機能しないためです。
  6. ハッシュを変更した直後にonhashchangeイベントを使用するプロキシフレームは、postMessageを使用してトークンを送信し(ドメインが異なるため)、承認のために開いているウィンドウ/タブを閉じます。
  7. onmessageイベントを使用するアプリケーションは、トークンを受け取り、そのトークンを目的に合わせて既に使用しています。









回路図画像









しかし、美しいパターンによると、私は特別ではありません。 しかし、それが明確になることを願っています。



デモンストレーション



このページでは、実際のサーバーがプルされないようにOAuth認証自体がシミュレートされることを除いて、 ライブの例を見ることができます



通常モードでは、トークン転送は非常に高速であるため、テキストフィールドのあるページは表示されません(すぐに閉じます)。 したがって、詳細を確認したい人は、5秒の遅延でウィンドウが閉じる例です。



postMessageについて他に読むべきこと



learn.javascript.ru/cross-window-messaging-with-postmessage

javascript.ru/ajax/cross-origin-2

html5demos.com/postmessage2

habrahabr.ru/post/120336

caniuse.com/#search=postmessage



PS興味があれば、デモのソーススクリプトをアーカイブに入れることができます。



All Articles