App Flip สําหรับ Android

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

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

ดูตัวอย่าง

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

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

วิธีการทำงาน

ต้องทำตามขั้นตอนต่อไปนี้เพื่อผสานรวม App Flip

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

แก้ไขแอป Android ให้รองรับ App Flip

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

  1. เพิ่ม <intent-filter> ลงในไฟล์ AndroidManifest.xml โดยใช้การดำเนินการ สตริงที่ตรงกับค่าที่คุณป้อนในช่อง 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. ดึงข้อมูลรหัสไคลเอ็นต์จากพารามิเตอร์ Intent และยืนยันว่าไคลเอ็นต์ รหัสตรงกับค่าที่คาดไว้

    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()
    

เนื้อหาของความตั้งใจในการเปิดตัว

Intent ของ 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 เพื่อ ตรวจสอบว่าได้แยกวิดีโอสำรองที่เหมาะสมแล้ว