Android 向けアプリ切り替え

OAuth 2.0 を実装すると、OAuth ベースの App Flip を設定できるようになります。これにより、Android ユーザーは認証システムのアカウントを Google アカウントに簡単にリンクできます。以降のセクションでは、smart home アクション用に App Flip を設計および実装する方法について説明します。

設計ガイドライン

このセクションでは、App Clip アカウントのリンクの同意画面の設計要件と推奨事項について説明します。Google がアプリを呼び出すと、同意画面がユーザーに表示されます。

要件

  1. ユーザーのアカウントが Google Home や Google アシスタントなどの特定の Google サービスではなく、Google にリンクされていることを通知する必要があります。

おすすめ

次の手順を行うことをおすすめします。

  1. Google のプライバシー ポリシーを表示する。同意画面に Google のプライバシー ポリシーへのリンクを追加する。

  2. 共有するデータです。明確で簡潔な表現を使用して、Google に必要なデータとその理由をユーザーに伝えます。

  3. 行動を促す明確なフレーズ。同意画面に「同意してリンクする」などの明確な行動を促すフレーズを記載する。これは、ユーザーがアカウントをリンクするために Google と共有する必要があるデータを理解する必要があるからです。

  4. 解約が可能。ユーザーがリンクを選択しない場合、前の画面に戻る、またはキャンセルするための手段を用意します。

  5. リンクを解除する権限。ユーザーがプラットフォームのリンクを解除するためのメカニズム(プラットフォームのアカウント設定の URL など)を提供する。または、リンクされたアカウントをユーザーが管理できる Google アカウントへのリンクを追加することもできます。

  6. ユーザー アカウントを変更できる。ユーザーがアカウントを切り替える方法を提案する。これは特に、ユーザーが複数のアカウントを持っている場合に有効です。

    • アカウントを切り替えるために同意画面を閉じる必要がある場合は、復元可能なエラーを Google に送信し、OAuth リンク暗黙的フローを使用して目的のアカウントにログインできるようにします。
  7. ロゴを含める。同意画面に会社のロゴを表示する。 スタイル ガイドラインを使用して、ロゴを配置します。Google のロゴも表示する場合は、ロゴと商標をご覧ください。

この図は、同意画面の設計の際に従うべき個々の要件と推奨事項を明記した同意画面の例です。
図 1: アカウントのリンクに関する同意画面の設計ガイドライン

OAuth ベースのアプリ切り替えを設定する

以下のセクションでは、OAuth ベースのアプリ切り替えの前提条件と、アプリ切り替えプロジェクトを Actions Console で設定する方法について説明します。

スマートホーム アクションを作成して OAuth 2.0 サーバーを設定する

アプリ切り替えを設定する前に、以下を行う必要があります。

Actions Console でアプリ切り替えを設定する

次のセクションでは、Actions Console でアプリ切り替えを構成する方法を説明します。

  1. [OAuth Client information](OAuth クライアント情報)のすべてのフィールドを入力します(アプリ切り替えがサポートされていない場合は、通常の OAuth がフォールバックとして使用されます)。
  2. [Use your app for account linking (optional)](アプリをアカウントのリンクに使用する(省略可))で、[Enable for Android](Android で有効にする)をオンにします。
  3. 次の各項目を入力します。
    • [Application ID](アプリ ID)。Application ID は、アプリに設定する固有の ID です。
    • [App signature](アプリ署名)。Android アプリは、インストールする前に公開鍵証明書で署名しておく必要があります。アプリ署名の取得について詳しくは、クライアントの認証をご覧ください。
    • [Authorization intent](認証インテント)。ここには、インテントのアクションを指定する文字列を入力します。
  4. クライアントを設定したい場合は、スコープを追加し、[Configure your client (optional)](クライアントを構成する(省略可))で [Add scope](スコープを追加)をクリックします。
  5. [保存] をクリックします。

Android アプリにアプリ切り替えを実装する

アプリ切り替えを実装するには、Google からのディープリンクを許可するようにアプリのユーザー認可コードを変更する必要があります。

OAuth ベースのアプリ切り替え(アプリ切り替え)を使用すると、Android アプリを Google アカウントのリンク フローに挿入できます。従来のアカウントのリンクフローでは、ユーザーがブラウザに認証情報を入力する必要があります。アプリ切り替えを使用すると、Android アプリへのログインを遅らせることができ、既存の承認を活用できます。ユーザーがアプリにログインしている場合は、アカウントをリンクするために認証情報を再入力する必要はありません。Android アプリにアプリ切り替えを実装するには、最小限のコード変更が必要です。

このドキュメントでは、アプリ切り替えをサポートするように Android アプリを変更する方法について説明します。

サンプルを試す

アプリ切り替えリンクのサンプルアプリは、Android でのアプリ切り替え対応アカウント リンクの統合を示しています。このアプリを使用すると、Google モバイルアプリから受信したアプリ切り替えインテントに応答する方法を確認できます。

サンプルアプリは、Android 用のアプリ切り替えテストツールと統合するように構成されています。このツールを使用して、Google とアカウントのリンクを設定する前に Android アプリと App Flip の統合を確認できます。このアプリは、アプリ切り替えが有効になっている場合に、Google モバイルアプリでトリガーされるインテントをシミュレートします。

仕組み

アプリ切り替えを統合するには、次の手順が必要です。

  1. Google アプリは、パッケージ名を使用して、アプリがデバイスにインストールされているかどうかを確認します。
  2. Google アプリは、パッケージ署名チェックを使用して、インストールされているアプリが正しいアプリであることを確認します。
  3. Google アプリがアプリ内の指定されたアクティビティを開始するためのインテントを作成します。このインテントには、リンクに必要な追加データが含まれます。また、Android フレームワークを通じてこのインテントを解決することで、アプリがアプリ切り替えをサポートしているかどうかを確認します。
  4. アプリは、そのリクエストが Google アプリから送信されていることを検証します。そのため、アプリはパッケージ署名と提供されたクライアント ID を確認します。
  5. アプリが OAuth 2.0 サーバーに認証コードをリクエストします。このフローが終了すると、認証コードまたはエラーが Google アプリに返されます。
  6. Google アプリが結果を取得し、アカウントのリンクを続けます。認証コードを指定すると、サーバー間のトークン交換は、ブラウザベースの OAuth リンクフローの場合と同じように行われます。

アプリ切り替えをサポートするように Android アプリを変更する

アプリ切り替えをサポートするには、Android アプリのコードを次のように変更します。

  1. [App Flip Intent] フィールドに入力した値と一致するアクション文字列を使用して、<intent-filter>AndroidManifest.xml ファイルに追加します。

    <activity android:name="AuthActivity">
      <!-- Handle the app flip intent -->
      <intent-filter>
        <action android:name="INTENT_ACTION_FROM_CONSOLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
    </activity>
    
  2. 呼び出し元アプリの署名を検証します。

    private fun verifyFingerprint(
            expectedPackage: String,
            expectedFingerprint: String,
            algorithm: String
    ): Boolean {
    
        callingActivity?.packageName?.let {
            if (expectedPackage == it) {
                val packageInfo =
                    packageManager.getPackageInfo(it, PackageManager.GET_SIGNATURES)
                val signatures = packageInfo.signatures
                val input = ByteArrayInputStream(signatures[0].toByteArray())
    
                val certificateFactory = CertificateFactory.getInstance("X509")
                val certificate =
                    certificateFactory.generateCertificate(input) as X509Certificate
                val md = MessageDigest.getInstance(algorithm)
                val publicKey = md.digest(certificate.encoded)
                val fingerprint = publicKey.joinToString(":") { "%02X".format(it) }
    
                return (expectedFingerprint == fingerprint)
            }
        }
        return false
    }
    
  3. インテント パラメータからクライアント ID を抽出し、クライアント ID が期待値と一致することを確認します。

    private const val EXPECTED_CLIENT = "<client-id-from-actions-console>"
    private const val EXPECTED_PACKAGE = "<google-app-package-name>"
    private const val EXPECTED_FINGERPRINT = "<google-app-signature>"
    private const val ALGORITHM = "SHA-256"
    ...
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val clientId = intent.getStringExtra("CLIENT_ID")
    
        if (clientId == EXPECTED_CLIENT &&
            verifyFingerprint(EXPECTED_PACKAGE, EXPECTED_FINGERPRINT, ALGORITHM)) {
    
            // ...authorize the user...
        }
    }
    
  4. 認証が成功したら、結果の認証コードを Google に返します。

    // Successful result
    val data = Intent().apply {
        putExtra("AUTHORIZATION_CODE", authCode)
    }
    setResult(Activity.RESULT_OK, data)
    finish()
    
  5. エラーが発生した場合は、代わりにエラー結果を返します。

    // Error result
    val error = Intent().apply {
        putExtra("ERROR_TYPE", 1)
        putExtra("ERROR_CODE", 1)
        putExtra("ERROR_DESCRIPTION", "Invalid Request")
    }
    setResult(-2, error)
    finish()
    

起動インテントの内容

アプリを起動する Android のインテントには次のフィールドがあります。

  • CLIENT_IDString): Google の client_id がアプリに登録されました。
  • SCOPEString[]): リクエストされたスコープのリスト。
  • REDIRECT_URIString): リダイレクト URL。

レスポンス データの内容

Google アプリに返されるデータは、setResult() を呼び出すことによってアプリ内で設定されます。このデータには次のものが含まれます。

  • AUTHORIZATION_CODEString): 認証コードの値。
  • resultCodeint): プロセスの成功または失敗について通知し、次のいずれかの値を取ります。
    • Activity.RESULT_OK: 成功を示します。認証コードが返されます。
    • Activity.RESULT_CANCELLED: ユーザーがプロセスをキャンセルしたことを示します。この場合、Google アプリは認証 URL を使用してアカウントのリンクを試みます。
    • -2: エラーが発生したことを示します。さまざまなエラーの種類を以下に示します。
  • ERROR_TYPEint): エラーのタイプ。次のいずれかの値になります。
    • 1: 回復可能なエラー: Google アプリは、認証 URL を使用してアカウントのリンクを試みます。
    • 2: 回復不能なエラー: Google アプリがアカウントのリンクを中止します。
    • 3: リクエスト パラメータが無効であるか、不明です。
  • ERROR_CODEint): エラーの性質を表す整数。各エラーコードの意味については、エラーコードの表をご覧ください。
  • ERROR_DESCRIPTIONString、省略可): 人が読めるエラーで、エラーを説明するメッセージ。

resultCode == Activity.RESULT_OK の場合、AUTHORIZATION_CODE の値は想定されています。それ以外の場合は、AUTHORIZATION_CODE の値を空にする必要があります。resultCode == -2 の場合、ERROR_TYPE 値が設定されます。

エラーコードの表

次の表は、各エラーコードと、それぞれが回復できるエラーであるか、回復できないエラーであるかを示しています。

エラーコード 意味 回復できる 回収不可
1 INVALID_REQUEST
2 NO_INTERNET_CONNECTION
3 OFFLINE_MODE_ACTIVE
4 CONNECTION_TIMEOUT
5 INTERNAL_ERROR
6 AUTHENTICATION_SERVICE_UNAVAILABLE
8 CLIENT_VERIFICATION_FAILED
9 INVALID_CLIENT
10 INVALID_APP_ID
11 INVALID_REQUEST
12 AUTHENTICATION_SERVICE_UNKNOWN_ERROR
13 AUTHENTICATION_DENIED_BY_USER
14 CANCELLED_BY_USER
15 FAILURE_OTHER
16 USER_AUTHENTICATION_FAILED

すべてのエラーコードについて、適切なフォールバックがトリガーされるように、setResult を介してエラー結果を返す必要があります。

デバイスでアプリ切り替えをテストする

アクションを作成し、コンソールとアプリでアプリ切り替えを設定したら、モバイル デバイスでアプリ切り替えをテストできます。アプリ切り替えをテストするには、Google アシスタント アプリまたは Google Home アプリを使用します。

アシスタント アプリからアプリ切り替えをテストする手順は次のとおりです。

  1. Actions Console に移動して、プロジェクトを選択します。
  2. 上部のナビゲーションで [Test](テスト)をクリックします。
  3. アシスタント アプリからアカウントのリンクフローをトリガーします。
    1. Google アシスタント アプリを開きます。
    2. [設定] をクリックします。
    3. [アシスタント] タブで、[スマートホーム] をクリックします。
    4. [追加(+)] をクリックします。
    5. プロバイダのリストからアクションを選択します。リストの先頭に「[test]」が付きます。リストから [test] アクションを選択する場合、アプリを開く必要があります。
    6. アプリが起動したことを確認し、承認フローのテストを開始します。

Home アプリからアプリ切り替えをテストする手順は次のとおりです。

  1. Actions Console に移動して、プロジェクトを選択します。
  2. 上部のナビゲーションで [Test](テスト)をクリックします。
  3. Home アプリからアカウントのリンクフローをトリガーします。
    1. Google Home アプリを開きます。
    2. [+] ボタンをクリックします。
    3. [デバイスのセットアップ] をクリックします。
    4. [セットアップ済みデバイスのリンク] をクリックします。
    5. プロバイダのリストからスマートホーム アクションを選択します。リストの先頭に「[test]」が付きます。リストから [test] アクションを選択する場合、アプリを開く必要があります。
    6. アプリが起動したことを確認し、承認フローのテストを開始します。