App Flip para Android

La vinculación de App Flip basada en OAuth (App Flip) inserta su aplicación de Android en el flujo de vinculación de la cuenta de Google. Un flujo de vinculación de cuentas tradicional requiere que el usuario ingrese sus credenciales en el navegador. El uso de App Flip difiere el inicio de sesión del usuario en su aplicación de Android, lo que le permite aprovechar las autorizaciones existentes. Si el usuario inició sesión en su aplicación, no es necesario que vuelva a ingresar sus credenciales para vincular su cuenta. Se requiere una cantidad mínima de cambios de código para implementar App Flip en su aplicación de Android.

En este documento, aprenderá a modificar su aplicación de Android para que sea compatible con App Flip.

Prueba la muestra

El tirón de aplicaciones que une aplicación de ejemplo demuestra una cuenta con capacidad para un tirón de aplicaciones que une la integración en Android. Puede usar esta aplicación para verificar cómo responder a una intención de Flip de aplicación entrante desde las aplicaciones móviles de Google.

La aplicación de ejemplo está preconfigurado para integrarse con la herramienta de prueba del tirón de aplicaciones para Android , que se puede utilizar para verificar la integración de su aplicación para Android con App tirón antes Configurar Cuenta vinculación con Google. Esta aplicación simula la intención desencadenada por las aplicaciones móviles de Google cuando App Flip está habilitado.

Cómo funciona

Se requieren los siguientes pasos para llevar a cabo una integración de App Flip:

  1. Los controles de la aplicación Google si su aplicación se instala en el dispositivo utilizando el nombre del paquete.
  2. La aplicación de Google utiliza una verificación de la firma del paquete para validar que la aplicación instalada es la correcta.
  3. La aplicación de Google crea la intención de iniciar una actividad designada en su aplicación. Esta intención incluye datos adicionales necesarios para la vinculación. También verifica si su aplicación es compatible con App Flip resolviendo esta intención a través del marco de Android.
  4. Su aplicación valida que la solicitud proviene de la aplicación de Google. Para hacerlo, su aplicación verifica la firma del paquete y el ID de cliente proporcionado.
  5. Su aplicación solicita un código de autorización de su servidor OAuth 2.0. Al final de este flujo, devuelve un código de autorización o un error a la aplicación de Google.
  6. La aplicación de Google recupera el resultado y continúa con la vinculación de la cuenta. Si se proporciona un código de autorización, el intercambio de tokens ocurre de servidor a servidor, de la misma manera que lo hace en el flujo de vinculación OAuth basado en navegador.

Modifica tu aplicación de Android para que sea compatible con App Flip

Para admitir App Flip, realice los siguientes cambios de código en su aplicación de Android:

  1. Añadir un <intent-filter> a su AndroidManifest.xml archivo con una cadena de acción que coincide con el valor introducido en el campo Intención tirón aplicación.

    <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. Valide la firma de la aplicación de llamadas.

    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. Extraiga la ID de cliente de los parámetros de la intención y verifique que la ID de cliente coincida con el valor esperado.

    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. Tras la autorización correcta, devuelva el código de autorización resultante a Google.

    // Successful result
    val data = Intent().apply {
        putExtra("AUTHORIZATION_CODE", authCode)
    }
    setResult(Activity.RESULT_OK, data)
    finish()
    
  5. Si ocurrió un error, devuelva un resultado de error en su lugar.

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

Contenido de la intención de lanzamiento

La intención de Android que lanza su aplicación incluye los siguientes campos:

  • CLIENT_ID ( String ): Google client_id registrada con su aplicación.
  • SCOPE ( String[] ): Una lista de los alcances solicitados.
  • REDIRECT_URI ( String ): La URL de redireccionamiento.

Contenido de los datos de respuesta

Los datos devueltos a la aplicación de Google se encuentra en su aplicación llamando setResult() . Estos datos incluyen lo siguiente:

  • AUTHORIZATION_CODE ( String ): El valor de código de autorización.
  • resultCode ( int ): Se comunica el éxito o el fracaso del proceso y toma uno de los valores siguientes:
    • Activity.RESULT_OK : Indica el éxito; se devuelve un código de autorización.
    • Activity.RESULT_CANCELLED : Señales de que el usuario ha cancelado el proceso. En este caso, la aplicación de Google intentará vincular la cuenta utilizando su URL de autorización.
    • -2 : Indica que se ha producido un error. A continuación se describen diferentes tipos de errores.
  • ERROR_TYPE ( int ): El tipo de error, que toma uno de los valores siguientes:
    • 1 : error recuperable: La aplicación de Google intentará vincular la cuenta utilizando la URL de autorización.
    • 2 : Error irrecuperable: aborta app La vinculación de cuenta de Google.
    • 3 : no válido o parámetros de la petición que faltan.
  • ERROR_CODE ( int ): Un entero que representa la naturaleza del error. Para ver lo que cada error medios de código, se refieren a la tabla de códigos de error .
  • ERROR_DESCRIPTION ( String , opcional): mensaje de estado legible que describe el error.

Un valor para el AUTHORIZATION_CODE Se espera que cuando resultCode == Activity.RESULT_OK . En todos los demás casos, el valor de AUTHORIZATION_CODE debe estar vacío. Si resultCode == -2 , entonces el ERROR_TYPE se espera que sea poblada valor.

Tabla de códigos de error

La siguiente tabla muestra los diferentes códigos de error y si cada uno es un error recuperable o irrecuperable:

Código de error Significado Recuperable Irrecuperable
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

Para todos los códigos de error, debe devolver el resultado de error a través setResult para asegurar el repliegue apropiado se trigerred.