Você pode permitir que seus usuários se autentiquem no Firebase usando o ID Apple deles usando o SDK do Firebase para realizar o fluxo de login OAuth 2.0 de ponta a ponta.
Antes de você começar
Para fazer login de usuários usando a Apple, primeiro configure Fazer login com a Apple no site do desenvolvedor da Apple e, em seguida, ative a Apple como provedor de login para seu projeto do Firebase.
Junte-se ao Programa de Desenvolvedores da Apple
Entrar com a Apple só pode ser configurado por membros do Apple Developer Program .
Configurar login com a Apple
O Apple Sign In deve estar ativado e configurado corretamente em seu projeto do Firebase. A configuração varia entre as plataformas Android e Apple. Siga a seção "Configurar login com a Apple" das plataformas da Apple e/ou guias do Android antes de continuar.Ativar a Apple como provedor de login
- No console do Firebase , abra a seção Auth . Na guia Método de login , habilite o provedor Apple .
- Defina as configurações do provedor de login da Apple:
- Se você estiver implantando seu aplicativo apenas em plataformas Apple, poderá deixar os campos ID do serviço, ID da equipe da Apple, chave privada e ID da chave vazios.
- Para suporte em dispositivos Android:
- Adicione o Firebase ao seu projeto Android . Certifique-se de registrar a assinatura SHA-1 do seu aplicativo ao configurá-lo no Firebase console.
- No console do Firebase , abra a seção Auth . Na guia Método de login , habilite o provedor Apple . Especifique o ID do serviço que você criou na seção anterior. Além disso, na seção de configuração do fluxo de código OAuth, especifique seu ID de equipe da Apple e a chave privada e o ID da chave que você criou na seção anterior.
Cumpra os requisitos de dados anônimos da Apple
Entrar com a Apple oferece aos usuários a opção de anonimizar seus dados, incluindo seu endereço de e-mail, ao fazer login. Os usuários que escolhem essa opção têm endereços de e-mail com o domínio privaterelay.appleid.com
. Ao usar o Login com a Apple em seu aplicativo, você deve cumprir todas as políticas ou termos de desenvolvedor aplicáveis da Apple em relação a esses IDs Apple anônimos.
Isso inclui a obtenção de qualquer consentimento necessário do usuário antes de associar qualquer informação pessoal de identificação direta a um ID Apple anônimo. Ao usar o Firebase Authentication, isso pode incluir as seguintes ações:
- Vincule um endereço de e-mail a um ID Apple anônimo ou vice-versa.
- Vincular um número de telefone a um ID Apple anônimo ou vice-versa
- Vincule uma credencial social não anônima (Facebook, Google, etc) a um ID Apple anônimo ou vice-versa.
A lista acima não é exaustiva. Consulte o Contrato de Licença do Apple Developer Program na seção Membership da sua conta de desenvolvedor para garantir que seu aplicativo atenda aos requisitos da Apple.
Acesse a classe firebase::auth::Auth
A classe Auth
é o gateway para todas as chamadas de API.- Adicione os arquivos de cabeçalho Auth e App:
#include "firebase/app.h" #include "firebase/auth.h"
- Em seu código de inicialização, crie uma classe
firebase::App
.#if defined(__ANDROID__) firebase::App* app = firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity); #else firebase::App* app = firebase::App::Create(firebase::AppOptions()); #endif // defined(__ANDROID__)
- Adquira a classe
firebase::auth::Auth
para seufirebase::App
. Há um mapeamento um para um entreApp
eAuth
.firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
Gerencie o fluxo de login com o SDK do Firebase
O processo de login com a Apple varia entre as plataformas Apple e Android.
Nas plataformas da Apple
Autentique seus usuários com o Firebase por meio do SDK Objective-C de login da Apple invocado a partir do seu código C++.
Para cada solicitação de login, gere uma string aleatória — um "nonce" — que você usará para garantir que o token de ID recebido foi concedido especificamente em resposta à solicitação de autenticação do seu aplicativo. Esta etapa é importante para evitar ataques de repetição.
- (NSString *)randomNonce:(NSInteger)length { NSAssert(length > 0, @"Expected nonce to have positive length"); NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; NSMutableString *result = [NSMutableString string]; NSInteger remainingLength = length; while (remainingLength > 0) { NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16]; for (NSInteger i = 0; i < 16; i++) { uint8_t random = 0; int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random); NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode); [randoms addObject:@(random)]; } for (NSNumber *random in randoms) { if (remainingLength == 0) { break; } if (random.unsignedIntValue < characterSet.length) { unichar character = [characterSet characterAtIndex:random.unsignedIntValue]; [result appendFormat:@"%C", character]; remainingLength--; } } } }
Você enviará o hash SHA256 do nonce com sua solicitação de entrada, que a Apple passará inalterada na resposta. O Firebase valida a resposta fazendo hash do nonce original e comparando-o com o valor passado pela Apple.
Inicie o fluxo de login da Apple, incluindo em sua solicitação o hash SHA256 do nonce e a classe delegada que tratará da resposta da Apple (veja a próxima etapa):
- (void)startSignInWithAppleFlow { NSString *nonce = [self randomNonce:32]; self.currentNonce = nonce; ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init]; ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest]; request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail]; request.nonce = [self stringBySha256HashingString:nonce]; ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]]; authorizationController.delegate = self; authorizationController.presentationContextProvider = self; [authorizationController performRequests]; } - (NSString *)stringBySha256HashingString:(NSString *)input { const char *string = [input UTF8String]; unsigned char result[CC_SHA256_DIGEST_LENGTH]; CC_SHA256(string, (CC_LONG)strlen(string), result); NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { [hashed appendFormat:@"%02x", result[i]]; } return hashed; }
Manipule a resposta da Apple em sua implementação de ASAuthorizationControllerDelegate`. Se o login for bem-sucedido, use o token de ID da resposta da Apple com o nonce sem hash para autenticar com o Firebase:
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) { if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential; NSString *rawNonce = self.currentNonce; NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent."); if (appleIDCredential.identityToken == nil) { NSLog(@"Unable to fetch identity token."); return; } NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding]; if (idToken == nil) { NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken); } }
Use a string de token resultante e o nonce original para criar uma credencial do Firebase e fazer login no Firebase.
firebase::auth::OAuthProvider::GetCredential( /*provider_id=*/"apple.com", token, nonce, /*access_token=*/nullptr); firebase::Future<firebase::auth::User*> result = auth->SignInWithCredential(credential);
O mesmo padrão pode ser usado com
Reauthenticate
que pode ser usado para recuperar novas credenciais para operações confidenciais que exigem login recente.firebase::Future<firebase::auth::SignInResult> result = user->Reauthenticate(credential);
O mesmo padrão pode ser usado para vincular uma conta ao Apple Sign In. No entanto, você pode encontrar um erro quando uma conta existente do Firebase já estiver vinculada à conta da Apple à qual você está tentando vincular. Quando isso ocorrer, o futuro retornará um status de
kAuthErrorCredentialAlreadyInUse
e o objeto UserInfo doSignInResult
pode conter umupdated_credential
válido. Essa credencial pode ser usada para fazer login na conta vinculada à Apple por meio deSignInWithCredential
sem a necessidade de gerar outro token de login da Apple e um nonce.Observe que você deve usar
LinkAndRetrieveDataWithCredential
para que esta operação contenha a credencial, poisupdated_credential
é um membro do objetoSignInResult.UserInfo
.firebase::Future<firebase::auth::SignInResult> link_result = auth->current_user()->LinkAndRetrieveDataWithCredential(credential); // To keep example simple, wait on the current thread until call completes. while (link_result.status() == firebase::kFutureStatusPending) { Wait(100); } // Determine the result of the link attempt if (link_result.error() == firebase::auth::kAuthErrorNone) { // user linked correctly. } else if (link_result.error() == firebase::auth::kAuthErrorCredentialAlreadyInUse && link_result.result()->info.updated_credential.is_valid()) { // Sign In with the new credential firebase::Future<firebase::auth::User*> result = auth->SignInWithCredential( link_result.result()->info.updated_credential); } else { // Another link error occurred. }
No Android
No Android, autentique seus usuários com o Firebase integrando o login OAuth genérico baseado na Web ao seu aplicativo usando o SDK do Firebase para realizar o fluxo de login de ponta a ponta.
Para lidar com o fluxo de login com o SDK do Firebase, siga estas etapas:
Construa uma instância de um
FederatedOAuthProviderData
configurado com o ID do provedor apropriado para a Apple.firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
Opcional: especifique escopos adicionais do OAuth 2.0 além do padrão que você deseja solicitar ao provedor de autenticação.
provider_data.scopes.push_back("email"); provider_data.scopes.push_back("name");
Opcional: se você quiser exibir a tela de login da Apple em um idioma diferente do inglês, defina o parâmetro
locale
. Consulte os documentos Entrar com a Apple para obter as localidades com suporte.// Localize to French. provider_data.custom_parameters["language"] = "fr"; ```
Depois que os dados do seu provedor forem configurados, use-os para criar um FederatedOAuthProvider.
// Construct a FederatedOAuthProvider for use in Auth methods. firebase::auth::FederatedOAuthProvider provider(provider_data);
Autentique-se com o Firebase usando o objeto do provedor Auth. Observe que, diferentemente de outras operações do FirebaseAuth, isso assumirá o controle da sua interface do usuário, exibindo uma visualização da Web na qual o usuário pode inserir suas credenciais.
Para iniciar o fluxo de login, chame
signInWithProvider
:firebase::Future<firebase::auth::SignInResult> result = auth->SignInWithProvider(provider_data);
Seu aplicativo pode aguardar ou registrar um retorno de chamada no Future .
O mesmo padrão pode ser usado com
ReauthenticateWithProvider
que pode ser usado para recuperar novas credenciais para operações confidenciais que exigem login recente.firebase::Future<firebase::auth::SignInResult> result = user->ReauthenticateWithProvider(provider_data);
Seu aplicativo pode aguardar ou registrar um retorno de chamada no Future .
E você pode usar
linkWithCredential()
para vincular diferentes provedores de identidade a contas existentes.Observe que a Apple exige que você obtenha o consentimento explícito dos usuários antes de vincular suas contas da Apple a outros dados.
Por exemplo, para vincular uma conta do Facebook à conta atual do Firebase, use o token de acesso obtido ao fazer login do usuário no Facebook:
// Initialize a Facebook credential with a Facebook access token. AuthCredential credential = firebase::auth::FacebookAuthProvider.getCredential(token); // Assuming the current user is an Apple user linking a Facebook provider. firebase::Future<firebase::auth::SignInResult> result = auth.getCurrentUser().linkWithCredential(credential);
Entrar com o Apple Notes
Ao contrário de outros provedores compatíveis com o Firebase Auth, a Apple não fornece um URL de foto.
Além disso, quando o usuário opta por não compartilhar seu e-mail com o aplicativo, a Apple fornece um endereço de e-mail exclusivo para esse usuário (no formato xyz@privaterelay.appleid.com
), que é compartilhado com seu aplicativo. Se você configurou o serviço de retransmissão de e-mail privado, a Apple encaminha os e-mails enviados para o endereço anônimo para o endereço de e-mail real do usuário.
A Apple só compartilha informações do usuário, como o nome de exibição, com aplicativos na primeira vez que um usuário faz login. Normalmente, o Firebase armazena o nome de exibição na primeira vez que um usuário faz login com a Apple, que você pode obter com getCurrentUser().getDisplayName()
. No entanto, se você usou a Apple anteriormente para fazer login de um usuário no aplicativo sem usar o Firebase, a Apple não fornecerá ao Firebase o nome de exibição do usuário.
Próximos passos
Depois que um usuário entra pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais, ou seja, o nome de usuário e a senha, o número de telefone ou as informações do provedor de autenticação com as quais o usuário fez login. Essa nova conta é armazenada como parte do seu projeto do Firebase e pode ser usada para identificar um usuário em todos os aplicativos do projeto, independentemente de como o usuário faça login.Nos seus aplicativos, você pode obter as informações básicas do perfil do usuário no objeto firebase::auth::user. Consulte Gerenciar usuários .
Nas regras de segurança do Firebase Realtime Database e do Cloud Storage, você pode obter o ID de usuário exclusivo do usuário conectado na variável de autenticação e usá-lo para controlar quais dados um usuário pode acessar.