App Flip สําหรับ Android

การเชื่อมโยงแอปพลิกแอปตาม OAuth (พลิกแอป) จะแทรกแอป Android ของคุณลงในขั้นตอนการเชื่อมโยงบัญชี Google ขั้นตอนการเชื่อมโยงบัญชีแบบเดิมกำหนดให้ผู้ใช้ป้อนข้อมูลประจำตัวในเบราว์เซอร์ การใช้ App Flip จะชะลอการลงชื่อเข้าใช้แอป Android ของผู้ใช้ ซึ่งทำให้คุณสามารถใช้การอนุญาตที่มีอยู่ได้ หากผู้ใช้ลงชื่อเข้าใช้แอปของคุณ พวกเขาไม่จำเป็นต้องป้อนข้อมูลรับรองอีกครั้งเพื่อเชื่อมโยงบัญชี ต้องมีการเปลี่ยนแปลงโค้ดเพียงเล็กน้อยเพื่อใช้ App Flip ในแอป Android ของคุณ

ในเอกสารนี้ คุณจะได้เรียนรู้วิธีแก้ไขแอพ Android ของคุณเพื่อรองรับ App Flip

ลองตัวอย่าง

พลิก App เชื่อมโยง แอปตัวอย่าง แสดงให้เห็นถึงบัญชีพลิกได้ App เชื่อมโยงบูรณาการบน Android คุณสามารถใช้แอปนี้เพื่อตรวจสอบวิธีตอบสนองต่อความตั้งใจของ App Flip ที่เข้ามาจากแอปมือถือของ Google

แอปพลิเคตัวอย่างจะถูกกำหนดไว้ล่วงหน้าเพื่อบูรณาการกับ App พลิกเครื่องมือทดสอบสำหรับ Android ซึ่งคุณสามารถใช้เพื่อตรวจสอบการรวม Android ของคุณแอปกับ App พลิกก่อนที่คุณกำหนดค่าบัญชีเชื่อมโยงกับ Google แอปนี้จำลองเจตนาที่เรียกใช้โดยแอปมือถือของ Google เมื่อเปิดใช้ App Flip

มันทำงานอย่างไร

จำเป็นต้องมีขั้นตอนต่อไปนี้เพื่อดำเนินการผสานรวม App Flip:

  1. ตรวจสอบแอป Google ถ้า app ของคุณจะถูกติดตั้งบนอุปกรณ์ที่ใช้ชื่อแพคเกจ
  2. แอป Google ใช้การตรวจสอบลายเซ็นแพ็กเกจเพื่อตรวจสอบว่าแอปที่ติดตั้งเป็นแอปที่ถูกต้อง
  3. แอป Google สร้างความตั้งใจที่จะเริ่มกิจกรรมที่กำหนดไว้ในแอปของคุณ ความตั้งใจนี้มีข้อมูลเพิ่มเติมที่จำเป็นสำหรับการเชื่อมโยง นอกจากนี้ยังตรวจสอบเพื่อดูว่าแอปของคุณรองรับ App Flip หรือไม่โดยแก้ไขจุดประสงค์นี้ผ่านเฟรมเวิร์กของ Android
  4. แอปของคุณตรวจสอบว่าคำขอมาจากแอป Google ในการดำเนินการดังกล่าว แอปของคุณจะตรวจสอบลายเซ็นแพ็กเกจและรหัสไคลเอ็นต์ที่ให้มา
  5. แอปของคุณขอรหัสการให้สิทธิ์จากเซิร์ฟเวอร์ OAuth 2.0 ของคุณ เมื่อสิ้นสุดขั้นตอนนี้ ระบบจะส่งคืนรหัสการให้สิทธิ์หรือข้อผิดพลาดไปยังแอป Google
  6. แอป Google จะดึงผลลัพธ์และดำเนินการต่อด้วยการเชื่อมโยงบัญชี หากมีการระบุรหัสการให้สิทธิ์ การแลกเปลี่ยนโทเค็นจะเกิดขึ้นแบบเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์ เช่นเดียวกับที่ทำในโฟลว์การลิงก์ OAuth บนเบราว์เซอร์

แก้ไขแอพ Android ของคุณเพื่อรองรับ App Flip

เพื่อรองรับ App Flip ให้ทำการเปลี่ยนแปลงโค้ดต่อไปนี้กับแอป Android ของคุณ:

  1. เพิ่ม <intent-filter> ที่คุณ AndroidManifest.xml ไฟล์ที่มีสตริงกระทำที่ตรงกับค่าที่คุณป้อนใน App ฟิลด์เจตนาพลิก

    <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. แยกรหัสลูกค้าจากพารามิเตอร์ความตั้งใจและตรวจสอบว่ารหัสลูกค้าตรงกับค่าที่คาดไว้

    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 ): URL เปลี่ยนเส้นทาง

เนื้อหาของข้อมูลตอบกลับ

ข้อมูลกลับไปยังแอป Google ตั้งอยู่ในแอปของคุณโดยการเรียก setResult() ข้อมูลนี้มีดังต่อไปนี้:

  • AUTHORIZATION_CODE ( String ): ค่ารหัสอนุมัติ
  • resultCode ( int ): สื่อสารความสำเร็จหรือความล้มเหลวของกระบวนการและใช้ค่าใดค่าหนึ่งต่อไปนี้:
    • Activity.RESULT_OK : บ่งบอกความสำเร็จ; รหัสการให้สิทธิ์จะถูกส่งคืน
    • Activity.RESULT_CANCELLED : สัญญาณว่าผู้ใช้มีการยกเลิกกระบวนการ ในกรณีนี้ แอป Google จะพยายามเชื่อมโยงบัญชีโดยใช้ URL การให้สิทธิ์ของคุณ
    • -2 : ระบุว่ามีข้อผิดพลาดเกิดขึ้น ข้อผิดพลาดประเภทต่างๆ ได้อธิบายไว้ด้านล่าง
  • ERROR_TYPE ( int ): ประเภทของข้อผิดพลาดซึ่งจะมีค่าใดค่าหนึ่งต่อไปนี้:
    • 1 : ข้อผิดพลาดที่กู้คืน: แอป Google จะพยายามเชื่อมโยงบัญชีใช้ URL อนุมัติ
    • 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 เพื่อให้แน่ใจว่าทางเลือกที่เหมาะสม trigerred