GoogleSignInを本番環境向けに設定して申請したら大変だった話

 こんにちは。マネックス・ラボでferciを開発している佐藤です。今回は、GoogleSignInで本番環境を意識した設定行った上で本番環境での利用を申請しようとしたところ、わからないことが多くて時間を使ってしまったので、本番環境を想定した設定の流れと、ハマりどころを書き残したいと思います。

f:id:fullstuck_sato:20211005105812j:plain:w320

Googleのロゴは勝手に使えないのでマカロンの画像を貼っておきます。

前提

 今回のGoogleSignInの利用は、モバイルアプリでのアカウント作成時に、GoogleアカウントをIDプロバイダとして使うことを想定しています。いろいろなアプリでよく見る、「Googleで続ける」ボタンの実装です。

f:id:fullstuck_sato:20211004190008j:plain:w320

 Googleアカウントから取得する情報はプロフィール情報(名前、プロフィール画像、メールアドレス)のみとします。いずれの情報も、Googleの定義上は「非機密のスコープ」に分類されます。「機密性の高いスコープ」または「制限付きのスコープ」を要求すると、より審査が厳しくなると予想されます。

 また、クライアントアプリケーションのコーディングと、公開ステータスがテストの状態での動作確認についての記事はたくさんあるため、ここでは触れません。

公式のドキュメント

 Webで検索すると、公式のドキュメントがなかなか出てこなくて苦労するので、ここにまとめておきます。プラットフォームごとに分かれているので、開発しているクライアントに合わせて目を通すと良いと思います。コーディングについては、サンプルコードが載っているので比較的容易に実装できるかと思います。

GCPの準備

 SignInWithAppleやFacebookログインなど他のサードパーティーログインもそうですが、IDプロバイダにクライアントアプリケーションを登録しておく必要があります。Appleであれば、AppleDeveloperですね。Googleの場合はなんと、GCPです。今回はモバイルアプリでGoogleSignInを実装しようとしていたので、GooglePlayConsoleではないことにとても違和感がありました。ただ、ネイティブアプリだけではなく、Webアプリケーションなどいくつものプラットフォームをサポートしていることや、Googleが提供しているサービスだと、GCPが無難な落とし所ではあるので、納得できるような気はします。

 ferciチームは他の要件ですでにGCPを使っていてプロジェクトが存在していたので、それを使うことにしました。もし、まだGCPを使っていなくてプロジェクトが無い、という場合には準備する必要があります。GCPのプロジェクトの作成については、これもまた検索すればたくさん情報が出てくると思いますので、割愛します。

OAuth2.0クライアントIDの登録

 GCPにアプリケーションのクライアントIDを登録します。登録が必要なクライアントIDはアプリケーションの構成によって変わってきます。ferciの場合にはネイティブアプリがGoogleにトークンを取得しに行き、ferciのサーバーアプリケーションがそのトークンを検証する構成にしているので、クライアントIDにはネイティブアプリのIDと、サーバーアプリケーションのID、合計二つを登録する必要がありました。この設定は、GCPのメニューから「APIとサービス」->「認証情報」を選んで行います。

f:id:fullstuck_sato:20211004190826p:plain

OAuth同意画面の設定

 次に、アプリの名前やアイコンの設定です。ここで設定した情報が、クライアントアプリで「Googleで続ける」を押した後に表示されるダイアログで利用されます。また、アプリケーションが求めるスコープもここで設定していきます。

f:id:fullstuck_sato:20211004190920j:plain:w320

 この設定は、GCPのメニューから「APIとサービス」->「OAuth同意画面」を開いて行います。やってみるとわかると思いますが、一つのGCPプロジェクトあたり、一つの設定だけを入れることができます。クライアントアプリのプラットフォームによって設定を変えたりすることはできないということでもあります。

f:id:fullstuck_sato:20211004191302p:plain:w640

 大事なことを一つ。OAuth同意画面の設定を開くと、右側にガイドという名のドキュメントがあります。言葉が独特で飲み込むのに時間がかかるのですが、その時の最新の情報が書かれているので、くまなく読んで理解することをお勧めします。

 それではアプリの設定を入れていきます。上記画面の「アプリを編集」を押します。4画面ほどのウィザード形式になっていますが、一気に説明していきます。画面キャプチャがあった方がわかりやすいとは思うのですが、公開できない情報だらけでマスクだらけになってしまうので、省略します。

「アプリを編集」の設定

アプリ名

 ユーザーに見せるためのものなので、正式な名前を慎重に入力しましょう。

ユーザーサポートメール

 同意画面のアプリ名をタップすると表示され、ユーザーから実際に問い合わせがくる可能性があるので、開発者の仕事用アドレスではなく、きちんと問い合わせに対応できるメールアドレスを設定しましょう。後で詳しく書きますが、このメールアドレスはGCPプロジェクトのオーナー権限を持つGoogleアカウントである必要があります。また、メーリングリストは設定できません。

アプリのロゴ画像

 JPEG,PNG,BMP形式のいずれかで、120 x 120pxの画像を用意して、アップロードします。

アプリのドメイン

 同意画面に表示される、Webサイト、プライバシーポリシーのURL、利用規約のリンクをそれぞれ設定します。

承認済みドメイン

 上記の「アプリのドメイン」で入力した3つのURLの、トップレベルのドメイン(www.monex.co.jpであれば、monex.co.jpという意味で書いています)を入力する必要があります。3つのURLは異なるドメインでも構いませんが、全てのドメインを入力する必要があります。また、この「承認済みドメイン」が結構難解で、ガイドに書かれている内容を引用すると、下記のように書かれています。

ドメインの所有権の確認
ドメインの所有権は、プロジェクトに関連付けられている 1 つ以上の Google アカウントの Google Search Console を通じて確認されます。

 もう少し具体的に書いて欲しいと思う文章ですが、要するに、GCPのプロジェクトに参加している誰でも良いから、Google Search Consoleで対象のドメインの所有権を確認済みにしてくださいね、ということです。

デベロッパーの連絡先情報

 これは、あまり悩むことは無いと思います。アプリのユーザーに公開されることはなく、本番環境への昇格の申請をする時にこのメールアドレス宛に連絡が来ます。

スコープの設定

 アプリケーションが求める権限を設定します。何を必要とするかはアプリケーションごとに変わるので、ここでは特に説明しません。

テストユーザー

 設定画面に書かれている通り、このアプリケーションでGoogleSignInできるテストユーザーを設定するのですが、今回の開発で試したところ、ここに設定しないユーザーでもGoogleSignInできてしまいました。要求するスコープに「機密性の高いスコープ」または「制限付きのスコープ」が含まれている場合には、ここに設定する必要があるのかもしれません。

本番環境への申請

 OAuth同意画面の公開ステータスに、「アプリを公開」ボタンがあります。

f:id:fullstuck_sato:20211004204721p:plain:w640

 これを押すと、下記の内容のダイアログが表示されます。

f:id:fullstuck_sato:20211004205204p:plain:w640

 特に2番が気になるところです。まさかのYouTuberデビューを求められるとは。ただ、これはおそらく求めるスコープに応じて必要になるもので、「非機密のスコープ」のみの場合には不要なのかもしれません。ferciの申請では、動画の作成を求められることはありませんでした。

 とにかく、アプリケーションやその時のGoogleの方針によって提供しないといけない情報が変わってくると思うので、ここは黙ってダイアログの「確認」ボタンを押します。押すと、ステータスが以下のように「確認ステータス」に変わります。そして新しく、「確認を準備する」というボタンが現れます。

f:id:fullstuck_sato:20211004192044p:plain:w640

確認を準備する

 もう、日本語訳がおかしい気がしますが、とにかく上記の「確認を準備する」ボタンを押します。押すと、これまでに入力したOAuth同意画面の情報に加えて、追加で入力が必要な項目が表示されます。ここでは、追加で設定が必要な項目のみ記述します。

省略可能な情報

 ここでは、審査の時にGoogleの担当者が参考にする情報を入力します。GoogleSignInを使う目的を記述する欄がありますので、なるべく簡潔かつ正確に説明を書きます。(YouTubeの動画を作りたくないので必死です。)今回のferciの申請時には、アプリケーションの説明を1行、GoogleSignInを使う理由を1行、Googleアカウントから何を取得するのかの概要を1行で書き、さらに取得する項目ごとにどのような目的で使うのかを1行ずつ、全体で6行書きました。これに対しての質問は来なかったので、これくらいの粒度で書けば十分なのかもしれません。

YouTube動画について

 結局のところ、今回の申請ではYouTube動画の提出は求められませんでした。「確認を準備する」で追加の情報を入力する時にも、入力欄すらありませんでした。おそらく、アプリケーションの機能や求めるスコープによっては、別途審査担当者からメールで連絡が来て、提出を求められる場合があるのでしょう。

審査で指摘されたこととGoogle担当者とのやり取りについて

 詳細はこの記事のあとの方で書こうと思うのですが、FirebaseAnalyticsを使っていた都合、所有権を確認しなければならないドメインにfirebaseapp.comのドメインが含まれており、申請を出した直後にすぐにメールが来て、検証に失敗したとの連絡を受けました。おそらく、ドメインの検証は機械的に行われ、失敗した時には1時間もかからずメールがくるので、来なければパスできたと考えて良いと思います。

 もう一つ、ドメインの検証を修正した後に再申請をしたところ、アプリのアイコンのURLが変更された、というメールが来ました。自分では変えておらず、ダッシュボードで見ても変わっていなかったので、Googleの実装上、再申請した時にURLが変わったのだろうと思ってそのままにしていました。しかし1週間経っても承認もリジェクトもされず、何の連絡も無いのでもう一度そのメールを読み返すと、リクエストのステップを確認したら、このメールに返信してくれ、とのこと。すっかり読み落としていました・・・簡潔に、申請内容を確認したから検証を進めてください、と返信したところ、2日後の日曜日(!)に承認されたという通知が来ました。

 全体では、最初に申請を出してから、2週間かからずに承認を得られました。メールの読み落としがなければおそらく3日あれば承認されたのではと思います。なお、ドキュメントには4〜6週間かかることが書かれています。申請者とGoogleの間でやりとりが発生したり、追加の情報が必要になった場合に、ワーストケースでこれくらいかかる、という目安なのだろうと思います。

 なお、Google担当者とのメールのやり取りは、全て英語になります。しかし今はGoogle翻訳が優秀なので、特に恐れる必要はないかと思います。くれぐれも、読み落としの無いように気をつければ大丈夫です。

ハマりどころ

いくつかドキュメントを読んでも分からず、苦戦したところがあるので補足しておきます。

ユーザーサポートメールの制約

 ユーザーサポートメールは前述した通り、アプリケーションのユーザーが問い合わせをするために設定します。問い合わせを受け付けるアドレスということは、一般的なサービスの運用では、複数人の社員が問い合わせに対応できるよう、メーリングリストでアドレスを作成し、公開することが多いと思います。しかしここにハマりポイントがあります。

 ユーザーサポートメールには、なんとGCPのプロジェクトに対してオーナー権限を付与する必要があります。公式のドキュメントを探しても明記されていないのですが、Stackoverflowに記事があったり、何人かの開発者のアカウントで検証した結果、オーナー権限を持っていないと設定時のプルダウンリストに候補として出てこないので間違いないと判断しています。なお、オーナー権限というのは一番強い権限であって、無闇に設定はしたくはないのですが、Googleの仕様であれば、従わざるを得ません。

 そして、問い合わせ窓口用のメーリングリストにオーナー権限を付与すると、今度は、グループにオーナー権限は付与できません、というエラーに遭遇しました。メーリングリストは複数人で使うものなので、それに対してオーナー権限を設定できるというのは確かに好ましくない話です。結局のところ、ユーザーサポートメールには問い合わせ窓口用のメーリングリストのアドレスを設定できないことになりました。

 こうなってくると仕方ないので、見た目はサポート窓口のアドレスで、実態は個人のメールアドレスとして問い合わせ先アドレスを作る、という対応をせざるを得ませんでした。もっと良い方法があればいいのですが。この仕様を知って、1ヶ月ほど考えたり、調べたりしましたが、これ以外の解決策にはたどり着きませんでした。

「承認済みドメイン」にfirebaseのドメインが含まれていてリジェクトされた

 承認済みドメインは、OAuth同意画面に表示する利用規約などのURLのドメインを設定し、Googleによって自動的にドメインの所有者であるかが検証されます。今回は、この検証でリジェクトされました。理由は、Firebase Hostingのドメインが自動的に追加されていたこと。ferciではFirebase AnalyticsやFCMを使う都合、サービス開始の当初から、Firebaseを利用していました。そして、申請する時点で<Firebaseのプロジェクト名>-<ランダムな文字列>.firebaseapp.comという、いかにもFirebase Hostingの仮ドメインのようなものが設定されていたので、審査に通るかどうか、心配していた部分でもありました。ただ、FirebaseとGCPは緊密に結びついており、Firebase経由でドメインの所有者として検証してもらえる可能性があったため、設定を残して申請を行ったという経緯もあります。

 色々と調べていくと、ferciはネイティブアプリの他に簡易なWeb版も提供しているのですが、Firebase側でWeb版のアプリを登録した時に、自動的にGCPの認証情報に、Web版のOAuthクライアントIDが登録されていたことがわかりました。そしてそこに、おそらくFirebase Hostingを使う時のドメインだと思うのですが、<プロジェクト名>-<ランダムな文字列>.firebaseapp.comというドメインがOAuthクライアントIDのプロパティである「承認済みのJavaScript生成元」に記述されており、このドメインがOAuth同意画面側にも自動で設定されていた、というものでした。

f:id:fullstuck_sato:20211005110418p:plain:w640

Web版のクライアントIDに、firebaseapp.comドメインが自動で設定されている。 これが、OAuth同意画面の承認済みドメインにも自動で追加されていた。

 ferciではFirebase Hostingは使っていないので、Web版のOAuthクライアントIDに設定されている「承認済みのJavaScript生成元」からfirebaseapp.comドメインを取り除き、その後、OAuth同意画面側の「承認済みドメイン」からも削除することができました。

最後に

 GoogleSignInは、特にドキュメントを読み解くのに苦労したので色々と書きたいことはあるのですが、無駄に長くなりそうなのでこの辺でまとめたいと思います。

 サードパーティーログインは、メールアドレスとパスワードによるアカウント作成と比べると、ユーザーに取っては手軽で、かつパスワードによる認証を必要としないので、IDプロバイダー側のアカウントさえきちんと守っていれば安全ということもあり、セキュリティ的にも良い認証方法の一つであると思います。ただし、きちんと管理されたIDプロバイダーを使うべきであり、それゆえに利用する際の申請の難しさのハードルはぐっと上がります。GoogleSignInはAppleとFacebookでのログインに比べて難しさを感じましたが、これだけ厳密な審査があるのであれば、信頼できるプロバイダであると言えることでもあり、むしろ安心して利用できるのではないかと考えています。

佐藤 俊介マネックス・ラボ