El vínculo de cambio de app basado en OAuth (cambio de app) inserta tu app para Android en la de vinculación de Cuentas de Google. Un flujo de vinculación de cuentas tradicional requiere la usuario ingrese sus credenciales en el navegador. El uso de App Flip aplaza al usuario acceder a tu app de Android, lo que te permite aprovechar autorizaciones. Si el usuario accedió a tu app, no es necesario volver a ingresar sus credenciales para vincular su cuenta. Una cantidad mínima de código se requieren cambios para implementar el cambio de app en tu app para Android.
En este documento, aprenderás a modificar tu app para Android de modo que admita Cambio de app
Prueba la muestra
La app de ejemplo de vinculación de app demuestra una integración de vinculación de cuentas compatible con cambio de app en Android. Tú pueden usar esta app para verificar cómo responder a un intent entrante de cambio de app desde Apps de Google para dispositivos móviles.
La app de ejemplo está preconfigurada para integrarse con la herramienta de prueba de cambio de app para Android que puedes usar para verificar la integración de tu app para Android con la Revisa la información antes de configurar la vinculación de cuentas con Google. Esta aplicación simula la intent que activan las apps de Google para dispositivos móviles cuando está habilitado el cambio de app.
Cómo funciona
Los siguientes pasos son obligatorios para realizar una integración de cambio de app:
- La app de Google verifica si tu app está instalada en el dispositivo a través de su package name.
- La app de Google usa una verificación de firma del paquete para validar que el servidor app es la correcta.
- La app de Google crea un intent para iniciar una actividad designada en tu app. Este intent incluye datos adicionales necesarios para la vinculación. También verifica para ver si tu app admite el cambio de app. Para ello, resuelve este intent a través del framework de Android.
- Tu app valida que la solicitud provenga de la app de Google. Para ello, sigue estos pasos: tu app verifica la firma del paquete y el ID de cliente proporcionado.
- Tu app solicita un código de autorización de tu servidor de OAuth 2.0. En el final de este flujo, devuelve un código de autorización o un error al app de Google
- La app de Google recupera el resultado y continúa con la vinculación de cuentas. Si se proporciona un código de autorización, se produce el intercambio del token servidor a servidor, tal como lo hace en la vinculación de OAuth basada en el navegador de tu flujo de trabajo.
Cómo modificar tu app para Android para que admita el cambio de app
Para admitir el cambio de app, realiza los siguientes cambios de código en tu app para Android:
Agrega un elemento
<intent-filter>
a tu archivoAndroidManifest.xml
con una acción string que coincida con el valor que ingresaste en el campo 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>
Valida la firma de la app que realiza la llamada.
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 }
Extrae el ID de cliente de los parámetros del intent y verifica que el cliente El ID coincide 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... } }
Una vez que la autorización se haya realizado correctamente, devuelve 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()
Si se produjo un error, muestra un resultado de error.
// Error result val error = Intent().apply { putExtra("ERROR_TYPE", 1) putExtra("ERROR_CODE", 1) putExtra("ERROR_DESCRIPTION", "Invalid Request") } setResult(-2, error) finish()
Contenido del intent de inicio
El intent de Android que inicia tu app incluye los siguientes campos:
CLIENT_ID
(String
):client_id
de Google registrado en tu app.SCOPE
(String[]
): Una lista de los permisos solicitados.REDIRECT_URI
(String
): Es la URL de redireccionamiento.
Contenido de los datos de respuesta
Los datos que se muestran a la app de Google se configuran en tu app llamando a setResult()
.
Entre estos datos, se incluyen los siguientes:
AUTHORIZATION_CODE
(String
): Es el valor del código de autorización.resultCode
(int
): Comunica el éxito o el fracaso del proceso. toma uno de los siguientes valores:Activity.RESULT_OK
: Indica que la operación se realizó correctamente. se devuelve un código de autorización.Activity.RESULT_CANCELLED
: Indica que el usuario canceló la el proceso de administración de recursos. En ese caso, la app de Google intentará vincular las cuentas con la URL de autorización.-2
: Indica que se produjo un error. Diferentes tipos de errores se describen a continuación.
ERROR_TYPE
(int
): Es el tipo de error, que toma una de las siguientes opciones: valores:1
: Error recuperable. La app de Google intentará vincular la cuenta con la URL de autorización.2
: Error irrecuperable: Google app anula la vinculación de cuentas.3
: Parámetros de solicitud no válidos o faltantes.
ERROR_CODE
(int
): Es un número entero que representa la naturaleza del error. Para ver qué significa cada código de error, consulta el tabla de códigos de error.ERROR_DESCRIPTION
(String
, opcional): Mensaje de estado legible por humanos al describir el error.
Se espera un valor para AUTHORIZATION_CODE
cuando
resultCode == Activity.RESULT_OK
En todos los demás casos, el valor para
El campo AUTHORIZATION_CODE
debe estar vacío. Si es resultCode == -2
, entonces el
Se espera que se propague el valor de ERROR_TYPE
.
Tabla de códigos de error
En la siguiente tabla, se muestran 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, debes mostrar el resultado del error a través de setResult
a
garantizar que se active el resguardo adecuado.