アプリ中でGoogle Calendar連携が必要なため、OAuth2の認証を使ったときのメモです。ちょっと力技な方法かもしれません。
GoogleのOAuth2認証では、ブラウザ側(以下STアプリ)では以下3つのパターンがあります。
1.すでに有効なトークンを持っている
2.トークンが無効だが、ブラウザ自体はGoogleにログイン状態になっている
3.トークンが無効で、ブラウザもGoogleにログオフ状態になっている
1.の場合は、特に対応に入りません。通常通りサーバー側のAPIにデータを投げればサーバー側でGoogleにデータを投げます。
2.の場合、サーバー側でGoogleにアクセスすると、認証に失敗します。この時、Googleから認証のためのURLを渡されますので、そのURLがSTアプリに渡されます。
ここで最初の注意が必要です。そのURLをwindow.openで開くとフルスクリーンアプリの場合、Safariが起動してしまいます。ログイン状態なためユーザーは何もしないまま、処理が完了し、完了画面を閉じて再度アプリを立ち上げるなければなりません。
このケースでは、cardレイアウトに以下のようなviewを渡しました。
Ext.define("Ext.view.GoogleLogin", {
extend: "Ext.form.Panel",
config: {
layout: 'vbox',
items: [
{
xtype: 'container',
flex: 1,
html: '<iframe src="" id="googleLogin" style="border:0;"></iframe>'
},
{
xtype: 'container',
flex: 10,
style: 'font-size: 18px;text-align:center;',
html: '処理中です。<br>しばらくお待ちください。'
}
]
}
});
そして、サーバーから受け取ったURLをこのiframeに渡します。ログインが不要であれば、このiframe内で処理が完了します。完了後のリダイレクト先を同一ドメイン内に指定し、リダイレクト先のJavaScriptから認証前の登録処理を再実行する関数を呼び出します。画面遷移なしで処理を完了できます。
3.の場合はGoogleへのログインが必要になります。セキュリティ上の問題で、認証用のログイン画面はiframe内に表示させることができません。画面遷移させる必要があるのですが、2.との切り分けが難しいです。3.のケースでは、iframe内でGoogleのログイン画面に遷移させようとして、できないためエラーが発生する、という状況になります。したがって、iframeのsrc(url)が変化したときのイベントをハンドルして後続の処理につなげたいのですが、そのようなAPIは存在しないようです。
仕方なく、最初にiframeにGoogle認証URLを与えてからsetIntervalで3秒待ったのちに、iframeのsrcを調べ、2.の処理完了のURLでないときは再度認証画面へ遷移させる、という方法をとりました。
次に、画面遷移の方法です。フルスクリーンの場合、window.openではSafariが開いてしまいます。そこで、
location.href = googleLoginURL;
として、フルスクリーンのまま画面全体がグーグルのログイン画面に遷移するようにしました。
なお、Androidでフルスクリーンにして使っていない場合は、普通にwindow.openの方が便利なので、切り分けて対処しました。
一般的には、どうされているのでしょうか。サーバー側の実装にもよりますが、こんなまどろこしいことせずに、ネイティブアプリのガワをつくって対処させるものなのでしょうか。