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:
- O Google app verifica se o app está instalado no dispositivo usando o nome do pacote.
- O Google app usa uma verificação de assinatura de pacote para confirmar que o app é o correto.
- 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.
- 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.
- 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.
- 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:
Adicione um
<intent-filter>
ao arquivoAndroidManifest.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>
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 }
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... } }
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()
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
): Googleclient_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.