yasutomogのブログ

Software Engineerの雑記

OAuth2対応したPWAをiOSでホーム画面に追加すると認証が厳しい

概要

  • 社内アプリをPWAで構築したときのはなし
  • 社内の諸々はGoogleアカウントで管理しているので、認証はGoogleのOAuth2を使用
  • PWAはNuxt.jsを使って作成し、APIPHPのLaravel(社内サイトがLaravelを使ってたので流用)を使って作成
  • Google OAuth 2.0 認証を使用

結論(感想)

  • Nuxt.jsを使うことで、単純なPWA構築はSPAの開発経験者であればいける(キャッシュ機構、バックグラウンド実行、オンラインとオフラインの切替時の制御とか、この辺のナレッジを溜めることでPWA経験者としての優位性が出てくると思う)
  • OAuth2を使用する場合、認証画面を開くときに単純なリダイレクト(ブラウザの別タブで表示される)にするよりかは、window.openで認証画面を開き、認証成功時にwindowを自動で閉じるような流れにするほうが、UI/UX的にいい感じな気がする
  • OAuth2の認証を使用すると、Androidでは想像通りの動きでいける。
    iOSではSafariで動かしているときにはAndroidと同様で問題ないが、ホーム画面に追加してPWAアプリとして起動するとOAuth2の認証が以下の理由で厳しい。
    • 認証画面の表示で、別ドメインのリダイレクトが必要なる
    • PWAから別ドメインを開くときは、window.openなどを使用してもSafariアプリのタブで開かれる
    • Safariアプリがアクティブ(PWAが非アクティブ)のときは、PWAでバックグラウンドの実行などはできないように制御されている
    • PWAをアクティブにしたときは、状態は破棄されてアプリ再起動と同様の動きになる
    • CookieやLocalStrageはPWAとSafariで同一ドメインでも共有できない(Androidだとこの辺はいける)
  • 以下のfirebaseのGitHubでも同様のissueが上がっているので、もう少し様子見していこうと思う github.com
  • 何か迂回策とかあれば教えてほしいです!

Google OAuth2.0のざっくりとしたフロー

  • PHPでログイン状態を確認して未ログイン状態であれば、Googleアカウントのログイン画面へリダイレクト
  • Googleアカウントで認証後、コールバックURLとして設定した自分のサイトへリダイレクトされる
  • 自分のサイト内で、認証情報などを取得して、DBなりCookieなりに保存する

Androidの場合(ケース1)

  • 「ホーム画面に追加」したPWAの処理について
  • PWAで用意した認証ボタンをクリックしたときに、API側でGoogle認証画面へリダイレクト
  • PWAとは別に、通常のChromeブラウザで別タブが開かれて、Google認証画面が表示される
  • Chromeブラウザ上で認証したときに、Cookieに認証情報登録
  • PWAに戻ると、(同一ドメインで構築の場合)Chromeで登録した認証情報にアクセスできるので、それを使い認証が必要な機能の使用が可能となる

ケース1の簡易フロー
ケース1の簡易フロー

Androidの場合(ケース2)

  • Googleの認証画面へリダイレクトするAPI呼び出しをするときに、window.openを使用する
  • PWA上でwindowがフルサイズで開き、Google認証画面が表示される
  • ケース1とほぼ同じで、認証後はその情報を使い認証が必要な機能の使用が可能となる
  • ケース1よりも良い点としては、認証後のタイミングをpostMessageなどを使用することでイベント検知できるので、認証完了したときにwindowを自動で閉じて、認証後の初期ページに遷移など制御をすることが可能

ケース2の簡易フロー
ケース2の簡易フロー

iOS safariの場合

  • 「 ホーム画面に追加」したPWAを使用して検証
  • PWAからOAuth2を使用するためにGoogle認証画面にリダイレクトすると、iOS safariの別タブとして起動される(window.openを使用してもiOS safariが起動される)
  • Androidでは、PWAとChromeブラウザでは、同一ドメインCookieであればお互い参照することが可能だったが、iOSのPWAとsafariではお互いのCookieにはアクセスできないような制御となっている
  • iOSのPWAでは、アプリが起動中でもメインで動いていない場合には、バックグラウンドでの実行ができないため、iOS safariからpostMessageを使って認証後情報を連携しようとしてもできない
  • 上記理由から、現時点ではiOSでOAuth2を使いPWAの構築は厳しそう
  • もちろん、ホーム画面に追加せず、そのままsafari上ではOAuth2を使った制御も可能なため、解決方法が見つかるまではそれで進めたい

ケース3の簡易フロー
ケース3の簡易フロー