Google は、より安全かつ簡単な認証をデベロッパーに提供する取り組みを通じて、ユーザーがお気に入りのアプリやウェブサイトに簡単にアクセスできるようにしています。Google Identity Services(GIS)は進化を続けており、パートナーのエコシステムに計り知れない価値をもたらす認証ソリューションの開発も続いています。認証済み電話番号を認証フローに直接埋め込むなど、要望の多かった機能にも対応しています。

デベロッパー向けに重点を置いているのは、常にスムーズな操作を提供して、ユーザーがパートナーのプラットフォームを簡単に使い始めたり再訪したりできるようにすることです。同時に、デベロッパーがユーザーと確かな信頼関係を築けるようにすることにも留意しています。


Android

認証済み電話番号

ID プロバイダである私たちは、操作にユーザーの明確な同意を織り込みつつ、ユーザーの Google アカウントを活用して、デベロッパーに追加のユーザーデータをシームレスに提供できるようにする作業を進めています。電話番号がアカウント管理の重要な要素であることは承知しています。この点は、モバイルファーストのマーケットにあるユーザーにとっても、ID 認証や 2 要素認証の必要性が高まっているデベロッパーにとっても言えることです。

Android デバイスでは、デベロッパー側から、Google アカウントに紐付けられた認証済み電話番号を共有することを登録フローの一環としてユーザーにリクエストできるようになります。デベロッパーからは、SMS 認証でユーザーを保護するには大きなコストが必要だという声が寄せられています。今回、デベロッパーは簡単に
ユーザーに電話番号をリクエストできるようになります。この電話番号は Google が検証を済ませているものです。これにより、オンボーディング プロセス全体で SMS のコストを削減できます。

認証済み電話番号は、現在 Android 版 GIS で利用できます。今後、他のプラットフォームにも展開する予定です。


電話番号ヒント

デベロッパーがユーザーの電話番号をリクエストするもう 1 つの方法は、Android デバイスで新しい Phone Number Hint API を使うことです。デベロッパーが Phone Number Hint API を呼び出すと、ユーザーはデバイスの SIM カードの電話番号を共有できます。これは、登録やログインのフローとは関係なく利用できます。この API には追加のパーミッションは不要なので、ネイティブ Android API を呼び出す方法よりもお勧めです。デベロッパーは時間と作業量を減らすことができます。Phone Number Hint API は、ユーザーが Google アカウントにログインしていなくても利用できます。Google アカウントに情報が保存されることもありません。

ウェブ

ITP ブラウザの One Tap

ITP(Intelligent Tracking Prevention)ブラウザでは、サードパーティ Cookie の利用が制限されるので、ウェブでユーザーがトラッキングされることはありません。今回、iOS 版の Safari、Firefox、Chrome などの ITP ブラウザで、GIS One Tap が利用できるようになります。これにより、ユーザーとデベロッパーの両方のために、複数のプラットフォームで一貫したワンタップ操作を実現します。デベロッパーは、次のようなさまざまな理由で One Tap の利用を好んでいます。
  • ユーザーのコンバージョンの増加
  • 業界をリードするセキュリティ
  • パスワード管理に伴うリスクの削減
  • 専用のログインページや登録ページにリダイレクトせずにログインや登録を実現
  • パーソナライズしたプロンプトによる重複アカウントの削減と再訪ユーザーの自動ログイン

ITP ブラウザでの One Tap の UX は、次のようなウェルカム ページから始まります。

ユーザーが続行することを選ぶと、ポップアップ ウィンドウが開きます。ポップアップ ウィンドウの UX は、標準の One Tap ユーザー エクスペリエンスと同じです。


この新機能は、One Tap を有効にしているすべてのデベロッパーを対象に、2022 年 10 月 12 日にデフォルトとしてロールアウトされる予定です。さっそく ITP ブラウザで One Tap のサポートを始めたい方や、デフォルトのサポートをオプトアウトしたい方は、ドキュメントをご覧ください。

iOS と macOS

macOS プラットフォーム拡張

この数年間で Apple のエコシステムは拡大し、多くの異なるプラットフォーム(iOS、iPadOS、macOS、tvOS、watchOS)が含まれるようになりました。そこで、Apple エコシステムのサポート拡大に向けて、iOS と macOS 向け Google ログインの一環として、macOS サポートをリリースします。これにより、ネイティブ macOS アプリで中核的な GIS 操作(認証、認可、トークンの保存)がサポートされるようになります。

サポートの終了

サポートの終了予定

GIS ライブラリで利用できる新機能に加えて、今後のサポートの終了予定についてもお知らせします。
  • Android での Smart Lock for Passwords のサポート終了
  • ウェブサイト向け Google ログインのサポート終了 

Smart Lock for Passwords のサポート終了

Smart Lock for Passwords Android SDK のサポートが終了します。この機能は、パスワードの保存と取得、ID トークンのリクエスト、ログインヒントの取得をします。GIS ライブラリでは、Smart Lock for Passwords のすべての機能を利用できます。すべてのデベロッパーの皆さんには、新しい機能用に GIS ライブラリを使うことをお勧めします。既存の統合機能の Smart Lock for Passwords トラフィックは、デフォルトで GIS ライブラリにリダイレクトされます。デベロッパーによる変更作業は必要ありません。

ウェブサイト向け Google ログインのサポート終了

再度のお知らせになりますが、ウェブ アプリケーション向けの Google ログイン JavaScript プラットフォーム ライブラリは 2023 年 3 月 31 日に完全に提供が終了します。このサポート終了が皆さんのウェブ アプリケーションに影響しないことを確認してください。必要な場合には、移行の計画を立ててください。

以上の新機能が、デベロッパーとユーザーの両方に大きな価値を提供し続けることを期待しています。今後もデベロッパーの皆さんの ID 関連のニーズにお応えできることを楽しみにしています。詳しい使い方は、デベロッパー サイトをご覧ください。


1 回限りのコードを使用した SMS による確認をアプリに実装する場合は、新しい SMS User Consent API を利用できます。

SMS による確認は一般に、アプリに 2要素目の認証方法を追加する場合に用いられます。「1234」または「481236」といった 1 回限りのコードを含んだ SMS メッセージがユーザーの電話番号に送信され、ユーザーがアプリにコードを入力することで、自分が SMS メッセージを受信したことを確認できます。
差出人: SMS
メッセージ: あなたの 1 回限りのコードは 1234 です。
しかし、率直にいって、1 回限りのコードを入力する作業が好きなユーザーはいません。面倒なうえ、エラーの原因になります。そのため、アプリの確認という目的を果たすだけでなく、そのエクスペリエンスをできるだけシームレスなものにすることが重要です。

SMS User Consent API を使用すると、ユーザーに対して、1 回限りのコードを含んだ 1 通の SMS メッセージの読み取り許可を求めるプロンプトをアプリから表示できます。その後、アプリでメッセージを解析したうえで、SMS による確認のフローを自動的に完了できます。

1 回限りのコードを含んだ 1 通のテキスト メッセージの読み取り許可をユーザーに求めます。

すでに SMS Retriever API を使用している場合、SMS User Consent API によって SMS Retriever API のサポートが終了したり、置き換えられたりすることはありません。SMS Retriever API をサポートするためにアプリがメッセージを変更できない場合もあることから、Google では 2 つ目の API を追加します。

SMS User Consent API を実装する前に SMS Retriever API をチェックして、ご自身のアプリで機能するかどうかを確認してください。使用できる場合、ユーザーがプロンプトをスキップできるため、利便性が向上します。

API の概要

本稿では、この API の使用に慣れるための基礎的な内容を説明します。実装例を含むこの API についての詳細は、ドキュメントをご覧ください。

SMS User Consent API は Google Play 開発者サービスの一部です。使用するには、以下のライブラリのバージョン 17.0.0 以降が必要になります。

implementation "com.google.android.gms:play-services-auth:17.0.0"

implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"

手順 1: SMS メッセージの待ち受けを開始する

SMS User Consent API は、最大 5 分間、1 回限りのコードを含んだ SMS メッセージの着信を待ち受けします。自身の開始前に送信されたメッセージにアクセスすることはありません。

SMS User Consent API は、1 回限りのコード(数字を 1 つ以上含んでいる 4~10 個の英数字)が含まれていないメッセージや、ユーザーの連絡先に登録されている差出人から届いたメッセージの場合には、プロンプトを表示することはありません。

1 回限りのコードを送信する電話番号がわかっている場合は、senderPhoneNumber を指定できます。電話番号がわからない場合は、null を指定するとすべての番号に一致します。
SMS User Consent API を開始するには、次のように SmsRetriever オブジェクトを使用します。

smsRetriever.startSmsUserConsent(

   senderPhoneNumber /* または null */)

手順 2: メッセージの読み取りに関する同意をリクエストする

アプリが 1 回限りのコードを含むメッセージを受信すると、ブロードキャストによって通知されます。この時点では、届いたメッセージの読み取りに関する同意は得られていません。代わりに、ユーザーの同意を求めるプロンプトの表示を開始できる Intent が提供されます。

BroadcastReceiver に渡された Intent を使って、SMS User Consent API のプロンプトを表示します。

BroadcastReceiver において、extras 内で Intent を使ってプロンプトを表示します。
このインテントを開始すると、1 通のメッセージを読み取る許可を求めるプロンプトがユーザーに表示されます。

ユーザーには、アプリに読み取りを許可するテキスト全文が表示されます。

val consentIntent = extras.getParcelable<Intent>(

   SmsRetriever.EXTRA_CONSENT_INTENT)

startActivityForResult(

   consentIntent,

   SMS_CONSENT_REQUEST)

手順 3: 1 回限りのコードを解析して SMS による確認を完了する

ユーザーが [許可] をタップしたら、実際にメッセージを読み取ります。onActivityResult 内で、次のように data から SMS メッセージの全文を取得できます。

val message = data.

   getStringExtra(

       SmsRetriever.EXTRA_SMS_MESSAGE)

その後、この SMS メッセージを解析して、1 回限りのコードをバックエンドに渡します。

詳細

SMS User Consent API を利用することで、ユーザーの利便性を向上させることができます。1 回限りのコードを自動的に解析することで、ユーザーは SMS による確認のフローを簡単に完了して、元の作業に戻ることが可能です。

コード全体を含む詳細については、以下のドキュメントをご覧ください。

Posted by Takeshi Hagikura - Developer Relations Team






Laurence Moroney
デベロッパー アドボケート


多くのデベロッパーにとって、アプリ用認証システムの構築は、税金を払うことのように感じるものです。どちらもわかりにくく、行わざるを得ないタスクで、うまく対応しないととんでもない結果になる可能性があります。税金を払うために会社を始める人は誰もいないように、すばらしいログイン システムを作るためだけにアプリを開発する人もいません。どちらも避けることのできない代償であるように見えます。

今なら、少なくとも「認証税」からは逃れることができます。Firebase Authentication の力を借りれば、認証システムを完全に Firebase にアウトソースし、優れたアプリを構築することに集中できます。ユーザーが簡単にログインできるようになるだけでなく、独自に認証システムを実装する際に求められる、複雑な処理を理解する必要もなくなります。簡単に使い始めることができ、ユーザーができるだけ戸惑わないようなデザインとなっているユーザー エクスペリエンス(UX)コンポーネントもオプションで提供されています。また、オープン スタンダードを基にして構築されており、Google のインフラによって支えられています。




Firebase Authentication の実装は、比較的簡単に早く済みます。広く使われているログイン方法(Facebook、Google、Twitter、メールとパスワードなど)の中から提供したいものを Firebase コンソールから選択し、Firebase SDK をアプリに追加するだけで、アプリはRealtime DatabaseFirebase Storage独自のカスタム バックエンドのいずれかと安全に接続できるようになります。すでに認証システムをお持ちの方は、Firebase Authentication を別の Firebase 機能へのブリッジとして使用することもできます。

Firebase Authentication にはオープンソース UI ライブラリも含まれており、ユーザーに優れたエクスペリエンスを提供する際に欠かせない、さまざまな認証フローを効率的に構築できます。Firebase Authentication の UI には、パスワードのリセット機能、アカウントのリンク機能、複数のログイン方法がある場合に認知的負荷を減らすログイン時のヒント機能などがすべて組み込まれています。こうしたフローは、Google や YouTube、Android でログインやサインアップのプロセスを最適化するための長年の UX リサーチに基づいています。Firebase Authentication には、多くのアプリでログイン コンバージョンを大幅に改善することにつながった Android の Smart Lock for Passwords も含まれています。Firebase UI はオープンソースなので、インターフェースは完全にカスタマイズできます。どんなアプリに組み込んでも自然に見えます。必要に応じて、クライアント API を使って一から独自の UI を作成することもできます。

さらに、Firebase Authentication はオープン性とセキュリティを中核に据えて構築されており、セキュリティ、相互運用性、移植性を持つように設計された業界標準である OAuth 2.0 と OpenID Connect を活用しています。Firebase Authentication チームのメンバーは、このようなプロトコルの設計にも携わっており、その経験を基にして ID トークン、取り消し可能なセッション、ネイティブ アプリの偽装対策といった最新のセキュリティ手法を生み出しています。それによってアプリが使いやすくなるとともに、多くの一般的なセキュリティの問題も回避できます。また、コードは Google Security チームによる独立したレビューを受けており、サービスは Google のインフラで守られています。

Fabulous がログインを短時間で実装するために Firebase Authentication を使用



Fabulous は、ログイン システムを強化するために Firebase Authentication を使用しています。デューク大学先進後知恵研究センターの研究から生まれたこのアプリは、不適切な行動を慎み、健康的な習慣を身に付けるための取り組みを始め、最終的にはユーザーが健全に幸福な暮らしを送ることを支援することを目的としています。

Fabulous のデベロッパーは、アップデートを最低限に抑え、エンドユーザーの負担を軽くする簡単な初回起動フローを実装したいと考えました。また、サインアップする前にアプリを試せるよう、匿名オプションも設けたいと考えました。さらに、複数のログイン方法をサポートし、ユーザーのログインフローとアプリのルック アンド フィールに一貫性を持たせるオプションも求めていました。

「たった半日で認証を実装することができました。以前は、独自のソリューションの作成には何週間もかかり、プロバイダの API に変更が発生するたびにアップデートしなければなりませんでした」- Amine Laadhari, Fabulous CTO

Malang Studio が Firebase Authentication で商品化までの時間を月単位で短縮



Chu-Day(AndroidiOS に対応)は、カップルが重要な日を忘れないようにするためのアプリケーションです。このアプリは、キャラクター中心のゲーム型ライフスタイル アプリケーションを開発している韓国企業 Malang Studio が作成しました。

一般的に、カウントダウンや記念日関係のアプリはユーザーのログインを要求しません。Malang Studio は、カップルをつないで特別な記念日をともにカウントダウンできるようにすることで、Chu-day を特別なアプリにして差別化を図りたいと考えました。しかしこれにはログイン機能が必要で、ユーザーの脱落を防ぐシームレスなログイン プロセスも必要でした。

Malang Studio は、Facebook や Google のログインを利用することで、 1 日で初回起動フローをアプリに組み込むことができました。サーバー側の開発やデータベースについて考える必要はなく、Firebase User Management Console を活用し、ログイン実装の開発やテスト、ユーザーの管理を行うこともできました。

「Firebase Authentication は最低限の設定しか必要としないので、短時間で簡単にソーシャル アカウントへのサインアップが実装できました。コンソールで提供されるユーザー管理機能もすばらしく、簡単に認証システムを実装できました」- Marc Yeongho Kim, Malang Studio CEO 兼 創立者

Firebase Authentication の詳細については、デベロッパー サイトと Google I/O 2016 のセッション「Best practices for a great sign-in experience」をご覧ください。


Posted by Yoshifumi Yamaguchi - Developer Relations Team

図 1. メール / ユーザー ID 置換攻撃
多くのデベロッパーが、Plus.API の getAccountName や getId 使ってこのアンチパターンを実装しています。

問題のある実装例、コピー禁止
  • アクセス トークン置換攻撃 Android で Google を使ってサインインした後に、多くのアプリは GoogleAuthUtil.getToken を介して取得したアクセス トークンを、アプリのバックエンド サーバーにアイデンティティアサーションとして送信します。アクセス トークンは Bearer トークンであり、バックエンド サーバーはトークンが自身に対して発行されたかどうかを簡単には確認できません。悪意のある攻撃者は、ユーザーを誘導して別のアプリケーションにサインインさせて、別のアクセス トークンを使ってバックエンドへのリクエストを偽造することができてしまいます。

    図 2. アクセス トークン置換攻撃
    次の例のように、多くのデベロッパーは、GoogleAuthUtil を使ってこのアンチパターンを実装し、アクセス トークンを取得してこれをサーバーに送信して認証を行っています。

    問題のある実装例、コピー禁止

解決策
  1. アプリに上記のアンチパターンを構築した多くのデベロッパーは、ユーザーのプロファイルを得るために、デバッグのみの tokenInfo(www.googleapis.com/oauth2/v3/tokeninfo)を単純に呼び出しているか、不必要に G+(www.googleapis.com/plus/v1/people/me)エンドポイントを呼び出しています。これらのアプリは、代わりに Google が推奨する ID トークン フローこのブログ記事で説明)を実装する必要があります。移行ガイドを確認して、安全で効率的なパターンに移行してください。
  2. サーバーでドライブなどのその他の Google サービスへのアクセスが必要な場合、サーバー認証コードフローを使用する必要があります。このブログ記事も参考になります。 参考までに、サーバー認証コードフローを使用して ID トークンも取得できます。これから、追加のネットワーク呼び出しを行わずに、ユーザー ID / メール / 名前 / プロファイル URL を取得できます。移行ガイドを参照してください。

アプリのユーザー エクスペリエンスとパフォーマンスの改善

未だにサーバー認証に GoogleAuthUtil を使っているアプリが多く存在します。そのようなアプリのユーザーは、改善されたユーザー エクスペリエンスを使う機会を失い、一方デベロッパーは、複雑な実装をメンテナンスし続ける必要があります。
共通の問題として次のようなことが挙げられます:

不必要なパーミッションをリクエストし、冗長なユーザー エクスペリエンスを表示する

多くのアプリは GET_ACCOUNTS パーミッションをリクエストし、独自のピッカーにすべてのメールアドレスを表示します。メールアドレスの取得後、アプリは GoogleAuthUtil または Plus.API を呼び出して、基本サインインのための OAuth 同意を行います。これらのアプリでは、次のような冗長なユーザー エクスペリエンスが表示されます。
図 3. GET_ACCOUNTS 実行時パーミッションおよび冗長なユーザー エクスペリエンス

最大の問題は GET_ACCOUNTS パーミッションです。Marshmallow 以降では、このパーミッションは「連絡先」としてユーザーに表示されます。多くのユーザーは、この実行時パーミッションにアクセス権を与えたくありません。

解決策
新しいAuth.GOOGLE_SIGN_IN_API に切り替えて、直感的な 1 タップ インターフェースにすることで、合理的にユーザーとの同意形成を実現し、アプリにユーザーの名前、メールアドレス、およびプロフィール画像を取得できるようになります。ユーザーがアカウントを選択したときに、アプリは OAuth 認可を受け取り、ユーザーは他のデバイスに簡単にサインインできるようになります。詳細はこちらから


図 4. 新しい合理化された 1 タップ サインイン エクスペリエンス

バックエンド用に GoogleAuthUtil から ID トークンを取得する

改良版 Sign-In API をリリースする前は、GoogleAuthUtil.getToken は「マジック ストリング」を介して ID トークンを取得する方法が推奨されていました。

誤ったパターン、コピー禁止

GoogleAuthUtil.getToken はメールアドレスを必要とし、これは図 3 に示す望まれないユーザー エクスペリエンスの原因となります。また、名前、プロフィール画像 URL などのユーザーのプロファイル情報は、サーバーに保存する貴重な情報です。Auth.GOOGLE_SIGN_IN_API を介して取得された ID トークンにはプロファイル情報が含まれ、サーバーではこれらの取得するための追加のネットワーク呼び出しが不要となります。

解決策 新しい Auth.GOOGLE_SIGN_IN_API を使用している ID トークン フローに切り替えて、1 タップ エクスペリエンスを実現します。詳細については、このブログ記事移行ガイドも参考になります。

バックエンド用に GoogleAuthUtil から認証コードを取得する

以前、GoogleAuthUtil.getToken を使用して別の「マジック ストリング」を介してサーバー認証コードを取得することを推奨していました。

誤ったパターン、コピー禁止

この実装には図 3 に示す冗長なユーザー エクスペリエンスの可能性があるのに加え、ユーザーが過去アプリにサインインしたことがある場合に新しいデバイスに切り替えると、次のような紛らわしいダイアログが表示されるという問題があります。


図 5. 認証コードに GoogleAuthUtil.getToken を使用した場合に再訪ユーザーに表示される紛らわしい同意ダイアログ

解決策
この「オフライン アクセス権を持つ」同意ダイアログを簡単に回避するには、新しい Auth.GOOGLE_SIGN_IN_API を使用しているサーバー認証コードフローに切り替える必要があります。以前サインインしたユーザーに対しては、ダイアログを表示せずに認証コードが発行されます。詳細については、このブログ記事移行ガイドも参考になります。

常に GoogleAuthUtil.getToken を使う必要がありますか?

一般的には、GoogleAuthUtil.getToken を使うべきではありません。ただし、Android クライアントで REST API 呼び出しを行っている場合を除きます。そういった場合は代わりに Auth.GOOGLE_SIGN_IN_API を使用してください。可能な場合は必ず Google Play サービス SDK のネイティブ Android API を使用してください。これらの API は、Android 用 Google API で確認できます。
また、Google Play サービス SDK 9.0 以降では、GoogleAuthUtil.getToken および次の関連クラスを使用するために -auth の SDK の分岐を含める必要があります。
AccountChangeEvent/AccountChangeEventsRequest/AccountChangeEventsResponse
dependencies { compile 'com.google.android.gms:play-services-auth:9.0.0' }

Posted by Eiji Kitamura - Developer Relations Team



画面外レンダリングのオーバーヘッド削減

最近の一般的なウェブサイトには、ビデオ、ソーシャル ウィジェット、広告などのオリジンを跨いだコンテンツが埋め込まれています。こういったリソースを埋め込むことによって魅力的なコンテンツを提供できる一方、これによって大きなオーバーヘッドが発生し、ページ側からは制御できない不自然な動作が起きることがあります。最新バージョンの Chrome では、画面外のレンダリング パイプラインは実行されず、画面外にあるオリジンを跨いだフレームに対する requestAnimationFrame() コールバックは呼び出されません。これによって、不要な動作が削減されます。いくつかの人気モバイルサイトでは、ユーザーの使い勝手に影響を与えることなく、最大 30% の消費電力を節約できるようになります。

今回のリリースに追加されたその他の機能

  • Intersection Observer API によって、要素の重なりを検出し、非同期イベントとして受け取ることができるようになりました。これによって、負荷のかかるドキュメントのモニタリングが不要になります。 
  • 最新バージョンの Chrome では、パッシブ イベント リスナーがサポートされます。これによって、タップやホイール入力に対してスクロールをブロックすることなく JavaScript を実行できるようになります。 
  • Blob の構築とブラウザへの転送が非同期に実行されるようになりました。これによって、大きなデータファイルを移動してもページに不自然な動作が発生しなくなります。 
  • SameSite Cookie 属性によって、Cookie を同じドメインからのリクエストに限定できます。 
  • TLS で AES_256_GCM 暗号がサポートされるようになり、鍵のサイズで暗号を選ぶサーバーのセキュリティが改善されました。このようなサーバーでは、安全で鍵のサイズが短い暗号よりも、従来の 256 ビット暗号が優先されていました。 
  • Array.prototype.values() が導入され、配列の要素に対する反復操作が簡単になりました。 
  • computed property name を持つプロパティやメソッドに対して、function の name プロパティがわかりやすい名前を推測するようになりました。これによって、ラベルやエラー メッセージが明確になり、デバッグが簡単になります。 
  • for-of ループを構成するイテレータが途中で終了した場合にも、デベロッパーが作成した close() メソッドが呼ばれるようになりました。これによって、反復処理の終了時の処理が簡単になります。 
  • Symbol.species によって、Array や RegExp などのビルトイン クラスのサブクラス化が強化されます。具体的には、派生オブジェクトに対してカスタム コンストラクタが呼ばれるようになります。 
  • RegExp のサブクラスで exec() メソッドを上書きすることによって、マッチング アルゴリズムを変更できるようになりました。これによって、カスタム サブクラスの記述が簡単になります。 
  • 独自の Symbol.hasInstance() メソッドを実装し、instanceof 演算子の動作をカスタマイズできるようになりました。 
  • Clients.get(id) で Service Worker の Client オブジェクトを取得できるようになりました。 
  • ServiceWorker.postMessage() によって、ServiceWorkerGlobalScopeExtendableMessageEvent が発生するようになりました。これによって、メッセージが Service Worker の使用期間を延長し、正確なメッセージ ソースを提供できるようになります。 
  • HTML の referrerpolicy 属性によって、<a>、<area>、<img>、<iframe> の各要素のリファラー ヘッダーにどの情報を送信するかを制御できるようになりました。 
  • UIEvents KeyboardEvent |key| 属性によって、押されているキーの意味を確実に判定できるようになりました。 
  • OfflineAudioContext.length 属性によってバッチ オフライン オーディオ コンテキストの長さを検出できるようになりました。 

その他の変更点

  • onbeforeunload ダイアログに表示されるメッセージをカスタマイズする機能が削除されました。ユーザーを悪意あるウェブサイトから保護し、他のブラウザの機能に合わせるためです。
  • Android 向けの Chrome で、デスクトップ向けの Chrome と同じメディア パイプラインが使用されるようになりました。これによって、WebAudio のサポートが改善され、<audio> タグや <video> タグの再生レートを操作できるようになります。
  • 最新バージョンの Chrome では、ウェブ アニメーションの相互運用性が改善されました。具体的には、値のリストがサポートされ、キーフレーム名にダッシュを許容する仕様が削除されています。
  • border 画像の描画に、border style が必要になりました。これによって、仕様への準拠と相互運用性が改善されます。
  • flex item の子要素がパーセンテージを使用してサイズを指定できるようになりました。
  • TLS セキュリティの改善につながる ECDHE 暗号の導入により、DHE ベースの暗号は廃止予定となりました。Chrome 52 で削除される予定です。


Posted by Eiji Kitamura - Developer Relations Team



図 1. アプリの設定


アプリを指定すると、Google Sign-In、Google クラウド メッセージング、Google Analytics など、アプリで利用できるサービスを選択し個別の設定を行うための画面が表示されます。

[Google Sign-In] を選択します。これを利用するには、あなたの Android アプリの署名証明書の SHA-1 を取得する必要があります。この証明書はデバッグ版でもリリース版でもかまいませんが、このブログではデバッグ版を使用します。ただし、最終的に利用する予定のあるパッケージや証明書のペアすべてについて、1 つずつこのプロセスを繰り返さなければならないことに注意してください(本稿の最後のセクションでもっと詳しく説明します)。

デバッグ版の SHA-1 は、以下の keytool コマンドを実行して取得することができます。

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

SHA-1 が取得できたら、以下の図 2 のとおり、その情報を入力します。



図 2. Google Sign-in の有効化


これでプロジェクトの設定は完了です。Sign-In API を組み込む作業に取りかかれる状態になりました。ただし、バックエンド サーバーや追加のパッケージ名またはキーストアと連携させるプロジェクト設定が必要な場合は、以下の手順に進んでください。

サーバーの設定 - サーバーが同一プロジェクト内に登録されていることの確認

アプリのデータを格納するウェブ サーバーやクラウド サーバーを運用している場合、バックエンド用の OAuth クレデンシャルが必要です。この詳細については、ID トークンおよびサーバーの認証コードに関するドキュメントを参照してください。

上記のフローを利用する前には、Google デベロッパー コンソールでウェブ サーバーの登録が正しく行われているかどうかを確認する必要があります。ここまでの処理が完了すると、プロジェクトを選択する画面が表示されます。下記の図 3 を参照してください。



図 3. Google デベロッパー コンソールでプロジェクトに直接アクセス


プロジェクトを選択してから [Continue] ボタンを選択すると、直接 [Credentials] タブに移動できます。このタブでは、あらゆるタイプのクレデンシャルを管理できます。「OAuth 2.0 client IDs」セクションを確認してください。前述のセットアップ ウィザードで自動的に作成された「Web client」と「Android client for com.my.package.name」が表示されています。下記の図 4 を参照してください。



図 4.デベロッパー コンソールの [Credentials] タブ - ウェブ サーバーの OAuth クライアント情報


ここで、「Web client」のクライアント ID に注目してください。下記の図のとおり、アプリとサーバーの両方の ID が必要です(過去にプロジェクトを作成しており、そのプロジェクトの「Web application」に OAuth 2.0 クライアント ID がない場合は、[New Credentials]、[OAuth client ID] の順に選択して、クライアント ID を新規作成してください)。

バックエンド認証の ID トークン フローを利用する場合は、Android アプリの開発を開始する際に、GoogleSignInOptions にお使いのサーバーのウェブ クライアント ID を指定して ID トークンをリクエストします。

GoogleSignInOptions gso =
    new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(serverClientId)
        .requestEmail()
        .build();

続いてサーバー側で、オーディエンスとなるウェブ アプリケーションに、同じ OAuth クライアント ID を設定します。

GoogleIdTokenVerifier verifier =
    new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
        .setAudience(Arrays.asList(serverClientId))
        .setIssuer("https://accounts.google.com")
        .build();

検証が正常に終了すると、新たにサインインしたユーザーを認証し、セッションを発行することができます。

また、Google API へのバックエンド アクセスでサーバー認証コードフローを使用する場合も、Android 上でサーバーのウェブ クライアント ID を指定して、GoogleSignInOptions でサーバー認証コードをリクエストしてください。

GoogleSignInOptions gso =
    new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
        .requestServerAuthCode(serverClientId)
        .requestEmail()
        .build();

サーバー上では、OAuth クライアント ID と「クライアント シークレット」の両方が有効です。Google が提供しているサーバー SDK では、ダウンロードした JSON 構成ファイルをそのまま利用できます。「ダウンロード」アイコンをクリックして JSON ファイルをダウンロードし(図 4 を参照)、以下のコードで GoogleClientSecrets を作成します。

GoogleClientSecrets clientSecrets =
    GoogleClientSecrets.load(
        JacksonFactory.getDefaultInstance(),
        new FileReader(PATH_TO_CLIENT_SECRET_FILE));

この時点で、アプリはサインインしたユーザーの権限で認証済みの Google API にアクセスできるようになります。「クライアント シークレット」は文字どおりシークレット(秘密)なので、Android クライアントに公開することのないように注意してください。

複数環境の管理 - プロジェクトに別のクライアント ID を登録する

環境が異なれば(たとえば別のデベロッパーの環境や、本番環境とテスト環境の違いなど)、1 つのアプリに別々のパッケージ名が割り当てられたり、証明書が異なる(当然 SHA-1 キーも異なる)ことも珍しくありません。Google では、パッケージ名と SHA-1 で署名した証明書のフィンガープリントを組み合わせて使用し、Android アプリを一意に識別します。したがって Google デベロッパー コンソールでは、すべてのパッケージ名と SHA-1 フィンガープリントの組み合わせを登録しておくことが重要です。

たとえば、現在のパッケージのリリース版を登録するには、以下の図 5 で示すように [New Credentials]、[OAuth client ID] の順に選択します。続いてステップに従い、パッケージ名と本番環境のキーストアの SHA-1 を追加します。



図 5.デベロッパー コンソールの [Credentials] タブ - OAuth クライアント ID を追加で作成する

これであなたも、アプリを実行するさまざまな環境に対応し、ユーザーにリリースできるようになりました。

本稿によって、OAuth キーを登録する方法についての皆さんの理解が深まり、皆さんのアプリやサーバーのセキュリティの維持が以前より容易になることを願っています。詳細については、Google Developers サイトの Google Identity Platform のドキュメントを参照してください。

Posted by Eiji Kitamura - Developer Relations Team


Posted by Yoshifumi Yamaguchi - Developer Relations Team


図 1.第三者が偽の電子メールでサーバーにアクセス可能


これはユーザー エクスペリエンスが悪いというだけではなく、顧客データが盗まれ、悪用されるというリスクの問題でもあります。これを防ぐため、ユーザーがアプリにサインインする際に Google からトークンを取得し、このトークンをサーバーに渡すようにします。サーバーは、このトークンが本当に Google がそのアプリの正規ユーザー宛てに発行したものかどうかを確認します(オーディエンス設定に基づいて実行します。下図参照)。この時点でサーバーは、サインインしようとしているのがこのアプリの正規ユーザーであり、不正な攻撃者ではないことを確認できます。その後、サーバーは要求された詳細情報を返します。


図 2.第三者の偽のトークンを拒否する

このステップを見てみましょう。

ステップ 1: Google にサインインすると、Android アプリは ID トークン(*)を取得します。こちらはこのプロセスの一例です。これを実行するには、GoogleSignInOptions オブジェクトを作成するときに requestIdToken メソッドを呼び出します。

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)  
         .requestIdToken(getString(R.string.server_client_id))  
         .requestEmail()  
         .build();  
これには、サーバーのクライアント ID を取得する必要があります。この方法についての詳細は、こちらをご覧ください(ステップ 4 を参照)。

Android アプリで取得されたトークンは、HTTPS でサーバーに POST できます。次にサーバーはトークンを認証します。

(*)ID トークンは JSON Web Token であり、RFC7519 で定義されています。これは二者間の要求を安全に表現するためのメソッドであり、業界標準として公開されています。

ステップ 2: サーバーは Android クライアントからトークンを受け取ります。次にサーバーは、Google API Client ライブラリで提供されているメソッドを使用してこのトークンを認証します。このトークンが Google によって発行されたものであること、そして対象オーディエンスがこのサーバーであることが認証されます。

サーバーは GoogleIdTokenVerifier クラスを使ってトークンを認証し、その後、要求された識別情報データを抽出します。「sub」フィールド(getSubject() メソッドで取得する)では、安定した文字列識別子を取得できます。これを使用すれば電子メールアドレスが変更された場合でもユーザーを認証でき、データベースでユーザーを特定できます。ID トークン フィールドには他にも、名前、電子メールアドレス、写真へリンクされた URL などが利用できます。提供されたライブラリを使用してトークンを確認できる、Google App Engine でテスト済みのサーブレットのサンプルはこちらから入手できます。これらのライブラリを使えば、ネットワーク呼び出しがなくても、トークンをローカルで認証できます。

 GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)  
      // Here is where the audience is set -- checking that it really is your server  
      // based on your Server’s Client ID  
      .setAudience(Arrays.asList(ENTER_YOUR_SERVER_CLIENT_ID_HERE))  
      // Here is where we verify that Google issued the token  
      .setIssuer("https://accounts.google.com").build();  
 GoogleIdToken idToken = verifier.verify(idTokenString);  
 if (idToken != null) {  
      Payload payload = idToken.getPayload();  
      String userId = payload.getSubject();   
      // You can also access the following properties of the payload in order  
      // for other attributes of the user. Note that these fields are only  
      // available if the user has granted the 'profile' and 'email' OAuth  
      // scopes when requested. Even when requested, some fields may be null.  
      // String email = payload.getEmail();  
      // boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());  
      // String name = (String) payload.get("name");  
      // String pictureUrl = (String) payload.get("picture");  
      // String locale = (String) payload.get("locale");  
      // String familyName = (String) payload.get("family_name");  
      // String givenName = (String) payload.get("given_name");  
GoogleAuthUtil を使用してバックエンドに渡すトークンを取得している既存アプリをお持ちの場合、上記のような最新の ID トークン認証を行うライブラリやシステムに切り替える必要があります。サーバー側でのベスト プラクティスを実現するための推奨事項は、今後の記事でご紹介する予定です。

この記事では、認証テクノロジーを使用して、ユーザーの本人認証を行う方法を説明しました。次回の記事では、Google Sign-In API を認証に使用して、ユーザーがアプリやバックエンド サービスから Google ドライブ などの Google サービスへアクセスする方法などを説明する予定です。

Google の認証テクノロジーについての詳細は、デベロッパー向け Google Identity Platform サイトをご覧ください。

Posted by Eiji Kitamura - Developer Relations Team

こちらのドキュメントに掲載している API のプロパティや定数を変更することで、ボタンをカスタマイズすることもできます。

ブランディングのガイドラインはこちらを参照してください。さまざまなタイプのボタンをご利用いただけるよう、ボタン画像は PNG、SVG、EPS などの形式で、解像度も数種類用意しています。ボタンのローカライズにこれらのファイルを利用することもできますが、アプリのスタイルに合わせてボタンのデザインを変更する場合は、前述のガイドラインを参照してください。

この記事では、アプリの Android 側の処理のみを説明しています。アプリにはサーバー側の処理も含まれることが多く、そこでも認証情報を安全に扱いたいのではないでしょうか。

次回の投稿では、Google Sign-In でログインする場合のサーバー側のシナリオ、たとえば独自のサーバーに認証情報を安全に渡す方法や、パーミッションとユーザーから送信された認証情報を使用して Google Drive など Google のバックエンド サービスを利用する方法を説明します。

Posted by Eiji Kitamura - Developer Relations Team