Android 版 App Flip

OAuth 式應用程式翻轉連結 (App Flip) 可將 Android 應用程式插入 Google 帳戶連結流程。傳統的帳戶連結流程需要 請在瀏覽器中輸入自己的憑證。App Flip 會延後使用者的使用方式 登入 Android 應用程式,即可利用現有的 授權。如果使用者已登入您的應用程式,就不需要 重新輸入他們的憑證即可連結帳戶。只需要少量程式碼 您必須進行變更,才能在 Android 應用程式中實作 App Flip。

在本文件中,您會瞭解如何修改支援這項功能的 Android 應用程式 應用程式翻轉。

試用範例

應用程式翻轉連結範例應用程式 展現了 Android 與應用程式 Flip 相容的帳戶連結整合功能。個人中心 可以使用這個應用程式,驗證如何回應傳入的應用程式 Flip 意圖 使用 Google 行動應用程式

範例應用程式已預先設定為整合 App Flip Test Tool Android、 可用來驗證 Android 應用程式與應用程式的整合 設定與 Google 帳戶連結前,請先翻轉。這個應用程式會模擬 意圖。

運作方式

如要整合應用程式小裝置,請按照下列步驟操作:

  1. Google 應用程式會使用 套件名稱
  2. Google 應用程式會使用套件簽章檢查,驗證已安裝的應用程式 是正確的應用程式
  3. Google 應用程式會建立意圖,以便在應用程式中啟動特定活動。 這項意圖包含連結所需的額外資料。它還會檢查 來解析這項意圖,瞭解應用程式是否支援 App Flip 相關功能。 Android 架構。
  4. 您的應用程式會驗證要求是否來自 Google 應用程式。方法如下 應用程式會檢查套件簽章和提供的用戶端 ID。
  5. 應用程式向 OAuth 2.0 伺服器要求授權碼。在 在這個流程結束時,系統會將授權碼或錯誤傳回 Google 應用程式。
  6. Google 應用程式會擷取結果,並繼續進行帳戶連結。如果 系統會提供授權碼 伺服器對伺服器,與使用瀏覽器 OAuth 連結的方式相同 流程

修改 Android 應用程式以支援 App Flip

如要支援 App Flip,請對 Android 應用程式進行以下程式碼變更:

  1. 透過動作為 AndroidManifest.xml 檔案新增 <intent-filter> 字串,與您在「App Flip Intent」欄位中輸入的值相符。

    <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_ID (String):Google client_id 已在您的應用程式註冊。
  • SCOPE (String[]):要求的範圍清單。
  • REDIRECT_URI (String):重新導向網址。

回應資料的內容

系統會在應用程式中呼叫 setResult(),設定傳回 Google 應用程式的資料。 這類資料包括:

  • AUTHORIZATION_CODE (String):授權碼值。
  • resultCode (int):告知程序是否成功,以及 可使用下列其中一個值:
    • Activity.RESULT_OK:表示成效;系統隨即會傳回授權碼
    • Activity.RESULT_CANCELLED:表示使用者已取消 上傳資料集之後,您可以運用 AutoML 自動完成部分資料準備工作在這種情況下,Google 應用程式會使用 您的授權網址。
    • -2:表示發生錯誤。各種錯誤類型 。
  • ERROR_TYPE (int):錯誤類型,可能採取下列其中一種做法 值:
    • 1:可復原錯誤:Google 應用程式將嘗試使用 授權網址
    • 2:無法復原的錯誤:Google 應用程式會取消帳戶連結。
    • 3:請求參數無效或遺失。
  • ERROR_CODE (int):代表錯誤性質的整數。查看 請參閱 錯誤代碼表
  • ERROR_DESCRIPTION (String,選用):人類可讀的狀態訊息 說明文字。

AUTHORIZATION_CODE 的值預期為 resultCode == Activity.RESULT_OK。在所有其他情況下, 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 傳回錯誤結果,以供 確保系統重試適當的備用行為。