App Flip para Android

A vinculação de app baseado em OAuth (App Flip) insere seu app Android no Fluxo de vinculação da Conta do Google. Um fluxo de vinculação de contas tradicional exige que o usuário insira as credenciais dele no navegador. O uso do App Flip adia login em seu aplicativo Android, o que permite que você aproveite os benefícios de autorização. Se o usuário tiver feito login no app, ele não vai precisar reinserir as credenciais para vincular a conta. Uma quantidade mínima de código mudanças são necessárias para implementar o App Flip no seu app Android.

Neste documento, você aprende a modificar seu app Android para oferecer suporte App Flip

Testar o exemplo

App de exemplo (link em inglês) de vinculação do App Flip demonstra uma integração de vinculação de contas compatível com o App Flip no Android. Você pode usar este app para verificar como responder a uma intent do App Flip recebida de Apps para dispositivos móveis do Google.

O app de exemplo está pré-configurado para integração com a App Flip Test Tool para Android, que você pode usar para verificar a integração do seu aplicativo Android com o Vire antes de configurar a vinculação de contas com o Google. Este app simula acionada pelos apps para dispositivos móveis do Google quando o App Flip está ativado.

Como funciona

As etapas a seguir são necessárias para realizar uma integração do App Flip:

  1. O Google app verifica se o app está instalado no dispositivo usando o nome do pacote.
  2. O Google app usa uma verificação de assinatura de pacote para confirmar que o app é o correto.
  3. O Google app cria uma intent para iniciar uma atividade designada no app. Essa intent inclui dados adicionais necessários para a vinculação. Ele também verifica para conferir se o app é compatível com o App Flip, resolvendo essa intent pela Framework do Android.
  4. Seu app valida que a solicitação está vindo do Google app. Para isso, o app verifica a assinatura do pacote e o ID do cliente fornecido.
  5. Seu app solicita um código de autorização do servidor OAuth 2.0. No final desse fluxo, ele retorna um código de autorização ou um erro ao Google app.
  6. O Google app recupera o resultado e continua com a vinculação da conta. Se um código de autorização é fornecido, a troca de tokens ocorre de servidor para servidor, da mesma forma que na vinculação OAuth baseada no navegador fluxo

Modificar seu app Android para oferecer suporte ao App Flip

Para oferecer suporte ao App Flip, faça as seguintes mudanças de código no seu app Android:

  1. Adicione um <intent-filter> ao arquivo AndroidManifest.xml com uma ação string que corresponde ao valor inserido no campo Intent do App Flip.

    <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 a assinatura do app de chamada.

    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. Extraia o ID do cliente dos parâmetros de intent e verifique se o cliente O ID corresponde ao 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. Após a autorização, retornar o código de autorização resultante para o Google.

    // Successful result
    val data = Intent().apply {
        putExtra("AUTHORIZATION_CODE", authCode)
    }
    setResult(Activity.RESULT_OK, data)
    finish()
    
  5. Se ocorrer um erro, retorne um resultado de erro.

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

Conteúdo da intenção de lançamento

A intent do Android que inicia seu app inclui os seguintes campos:

  • CLIENT_ID (String): Google client_id registrado no app.
  • SCOPE (String[]): uma lista de escopos solicitados.
  • REDIRECT_URI (String): é o URL de redirecionamento.

Conteúdo dos dados de resposta

Os dados retornados ao Google app são definidos no app chamando setResult(). Esses dados incluem o seguinte:

  • AUTHORIZATION_CODE (String): o valor do código de autorização.
  • resultCode (int): comunica o sucesso ou fracasso do processo, e usa um dos seguintes valores:
    • Activity.RESULT_OK: indica sucesso. um código de autorização é retornado.
    • Activity.RESULT_CANCELLED: indica que o usuário cancelou o de desenvolvimento de software. Nesse caso, o Google app tentará vincular a conta usando seu URL de autorização.
    • -2: indica que ocorreu um erro. Diferentes tipos de erros estão descritas abaixo.
  • ERROR_TYPE (int): o tipo de erro, que usa uma das opções a seguir valores:
    • 1: erro recuperável: o Google app tentará vincular a conta usando o URL de autorização.
    • 2: erro irrecuperável: o Google app cancela a vinculação da conta.
    • 3: parâmetros de solicitação inválidos ou ausentes.
  • ERROR_CODE (int): um número inteiro que representa a natureza do erro. Para ver o significado de cada código de erro, consulte tabela de códigos de erro.
  • ERROR_DESCRIPTION (String, opcional): mensagem de status legível por humanos descrevendo o erro.

Um valor para AUTHORIZATION_CODE é esperado quando resultCode == Activity.RESULT_OK. Em todos os outros casos, o valor de O campo AUTHORIZATION_CODE precisa estar vazio. Se for resultCode == -2, o Espera-se que o valor ERROR_TYPE seja preenchido.

Tabela de códigos de erro

A tabela abaixo mostra os diferentes códigos de erro e se cada um é um erro recuperável ou irrecuperável:

Código do erro Significado Recuperável Irrecuperável
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 os códigos de erro, você precisa retornar o resultado de erro usando setResult para para garantir que o substituto apropriado seja acionado.