Você pode usar o SDK do Firebase para permitir que os usuários façam a autenticação com o Firebase usando o ID Apple deles para realizar todo o fluxo de login do OAuth 2.0.
Antes de começar
Para fazer login com usuários usando a Apple, primeiro configure o recurso Iniciar sessão com a Apple no site do desenvolvedor da Apple e a ative como um provedor de login para seu projeto do Firebase.
Participe do Programa para desenvolvedores da Apple
O recurso Iniciar sessão com a Apple só pode ser configurado por membros do Programa para desenvolvedores da Apple.
Como configurar o recurso "Iniciar sessão com a Apple"
No site do Desenvolvedor da Apple, faça o seguinte:
-
Associe seu site ao seu aplicativo conforme descrito na primeira seção de Configurar Login com a Apple para a Web. Quando solicitado, registre o URL a seguir como um URL de retorno:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
Você pode acessar o ID do projeto do Firebase na página de configurações do Console do Firebase.
Quando terminar, anote o novo ID de serviço, que será necessário na próxima seção.
- Crie um Login com a chave privada da Apple. Você precisará da sua nova chave privada e do ID da chave na próxima seção.
-
Se você usar qualquer um dos recursos do Firebase Authentication que enviam e-mails para os usuários, incluindo login com o link de e-mail, verificação de endereço de e-mail, revogação de alteração de conta e outros, configure o serviço de redirecionamento de e-mail privado da Apple e registre
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com
ou seu domínio de modelo de e-mail personalizado para que a Apple possa retransmitir os e-mails enviados pelo Firebase Authentication para endereços anônimos de e-mail da Apple.
Ativar a Apple como um provedor de login
- Adicione o Firebase ao seu projeto.
- No Console do Firebase, abra a seção Auth. Na guia Método de login, ative 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 do OAuth, especifique o ID de equipe da Apple, a chave privada e o ID da chave que você criou na seção anterior.
Obedeça aos requisitos de dados anônimos da Apple
O recurso Iniciar sessão com a Apple permite que os usuários deixem seus dados anônimos,
incluindo o 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 recurso Iniciar sessão com a Apple no seu aplicativo, você precisa estar em conformidade com todos os termos ou políticas do desenvolvedor aplicáveis da Apple relacionados a esses IDs anônimos da Apple.
Isso inclui obter o consentimento do usuário exigido antes de associar qualquer informação pessoal de identificação direta a um ID anônimo da Apple. O uso do Firebase Authentication pode incluir as seguintes ações:
- Vincular um endereço de e-mail a um ID Apple ou vice-versa.
- Vincular um número de telefone a um ID Apple anônimo ou vice-versa.
- Vincular uma credencial social não anônima (Facebook, Google etc.) a um ID Apple anônimo ou vice-versa.
Essa não é uma lista completa. Consulte o "Contrato de licença do programa para desenvolvedores da Apple" na seção de associação da sua conta de desenvolvedor para verificar se o app atende aos requisitos da Apple.
Processar o fluxo de login com o SDK do Firebase
Se você estiver criando um app da Web, a maneira mais fácil de autenticar seus usuários com o Firebase usando contas da Apple é gerenciar todo o fluxo de login com o SDK do Firebase para JavaScript.
Para processar o fluxo de login com o SDK do Firebase para JavaScript, siga estas etapas:
Crie uma instância de um OAuthProvider usando o ID de provedor apple.com correspondente.
Versão 9 para a Web
import { OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('apple.com');
Versão 8 para a Web
var provider = new firebase.auth.OAuthProvider('apple.com');
Opcional: especifique escopos adicionais do OAuth 2.0 além do padrão que você quer solicitar ao provedor de autenticação.
Versão 9 para a Web
provider.addScope('email'); provider.addScope('name');
Versão 8 para a Web
provider.addScope('email'); provider.addScope('name');
Por padrão, quando a opção Uma conta por endereço de e-mail é ativada, o Firebase solicita escopos de nome e e-mail. Se você alterar essa configuração para Várias contas por endereço de e-mail, o Firebase não solicitará nenhum escopo da Apple, a não ser que você os especifique.
Opcional: se você quiser exibir a tela de login da Apple em um idioma diferente do inglês, defina o parâmetro
locale
. Consulte Fazer login com os documentos da Apple para ver as localidades com suporte.Versão 9 para a Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Versão 8 para a Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Use o objeto de provedor do OAuth para a autenticação no Firebase. Você pode solicitar que os usuários façam login com suas "Contas da Apple" abrindo uma janela pop-up ou redirecionando para a página de login. O método de redirecionamento é recomendável para dispositivos móveis.
Para fazer login com uma janela pop-up, chame
signInWithPopup()
:Versão 9 para a Web
import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // The signed-in user info. const user = result.user; // Apple credential const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; // ... }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Versão 8 para a Web
firebase .auth() .signInWithPopup(provider) .then((result) => { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // The signed-in user info. var user = result.user; // You can also get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
Para redirecionar os usuários à página de login, chame
signInWithRedirect()
:Versão 9 para a Web
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
Versão 8 para a Web
firebase.auth().signInWithRedirect(provider);
Depois que o usuário concluir o login e retornar à página, você poderá ver o resultado do login chamando
getRedirectResult()
:Versão 9 para a Web
import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth"; // Result from Redirect auth flow. const auth = getAuth(); getRedirectResult(auth) .then((result) => { const credential = OAuthProvider.credentialFromResult(result); if (credential) { // You can also get the Apple OAuth Access and ID Tokens. const accessToken = credential.accessToken; const idToken = credential.idToken; } // The signed-in user info. const user = result.user; }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Versão 8 para a Web
// Result from Redirect auth flow. firebase .auth() .getRedirectResult() .then((result) => { if (result.credential) { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // You can get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // ... } // The signed-in user info. var user = result.user; }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
Também é nesse local que você identifica e corrige erros. Para receber uma lista de códigos de erro, consulte a Referência da API.
Diferentemente de outros provedores que suportam o Firebase Auth, a Apple não fornece um URL de foto.
Além disso, quando o usuário opta por não compartilhar e-mails com o app, a Apple fornece um endereço de e-mail exclusivo para esse usuário, no formato
xyz@privaterelay.appleid.com
, que é compartilhado com seu app. Se você tiver configurado o serviço de retransmissão de e-mail privado, a Apple encaminhará os e-mails enviados ao 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 apps 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
firebase.auth().currentUser.displayName
. No entanto, se você já usou a Apple para fazer login de um usuário no app sem usar o Firebase, a Apple não fornecerá ao Firebase o nome de exibição do usuário.
Reautenticação e vinculação de contas
O mesmo padrão pode ser usado com reauthenticateWithPopup()
e
reauthenticateWithRedirect()
, que você pode usar para recuperar uma nova
credencial para operações confidenciais que exigem login recente:
Versão 9 para a Web
import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth"; // Result from Redirect auth flow. const auth = getAuth(); const provider = new OAuthProvider('apple.com'); reauthenticateWithPopup(auth.currentUser, provider) .then((result) => { // User is re-authenticated with fresh tokens minted and can perform // sensitive operations like account deletion, or updating their email // address or password. // The signed-in user info. const user = result.user; // You can also get the Apple OAuth Access and ID Tokens. const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; // ... }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Versão 8 para a Web
const provider = new firebase.auth.OAuthProvider('apple.com'); firebase .auth() .currentUser .reauthenticateWithPopup(provider) .then((result) => { // User is re-authenticated with fresh tokens minted and can perform // sensitive operations like account deletion, or updating their email // address or password. /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // The signed-in user info. var user = result.user; // You can also get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
Além disso, você pode usar linkWithPopup()
e linkWithRedirect()
para vincular diferentes
provedores de identidade a contas existentes.
Observe que a Apple exige que você receba consentimento explícito dos usuários antes de vincular as contas da Apple a outros dados.
Por exemplo, para vincular uma conta do Facebook à conta atual do Firebase, use o token de acesso da assinatura do usuário no Facebook:
Versão 9 para a Web
import { getAuth, linkWithPopup, FacebookAuthProvider } from "firebase/auth"; const auth = getAuth(); const provider = new FacebookAuthProvider(); provider.addScope('user_birthday'); // Assuming the current user is an Apple user linking a Facebook provider. linkWithPopup(auth.currentUser, provider) .then((result) => { // Facebook credential is linked to the current Apple user. // ... // The user can now sign in to the same account // with either Apple or Facebook. }) .catch((error) => { // Handle error. });
Versão 8 para a Web
const provider = new firebase.auth.FacebookAuthProvider(); provider.addScope('user_birthday'); // Assuming the current user is an Apple user linking a Facebook provider. firebase.auth().currentUser.linkWithPopup(provider) .then((result) => { // Facebook credential is linked to the current Apple user. // Facebook additional data available in result.additionalUserInfo.profile, // Additional Facebook OAuth access token can also be retrieved. // result.credential.accessToken // The user can now sign in to the same account // with either Apple or Facebook. }) .catch((error) => { // Handle error. });
Fazer autenticação com o Firebase em uma extensão do Chrome
Se você está criando um app de extensão do Chrome, é necessário adicionar o ID da extensão:
- Abra seu projeto no Console do Firebase.
- Na seção Autenticação, abra a página Método de login.
- Adicione um URI como o seguinte à lista de domínios autorizados:
chrome-extension://CHROME_EXTENSION_ID
Somente as operações pop-up (signInWithPopup
, linkWithPopup
e reauthenticateWithPopup
) estão disponíveis
para as extensões do Chrome. Isso ocorre porque as extensões não podem usar
redirecionamentos de HTTP. Chame esses métodos usando uma página em segundo plano porque,
se usar o pop-up de ação do navegador, ele será cancelado pelo pop-up de autenticação. Os métodos
pop-up só podem ser usados em extensões que usam
o Manifest V2. O Manifest V3
mais recente só permite scripts em segundo plano na forma de service workers, que não podem realizar as operações
pop-up.
No arquivo de manifesto da sua extensão do Chrome, adicione o URL https://apis.google.com
à lista de permissões content_security_policy
.
Observe que você ainda precisa verificar o domínio personalizado com a Apple de forma semelhante ao domínio padrão firebaseapp.com:
http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt
Avançado: autenticar com o Firebase no Node.js
Para autenticar com o Firebase em um aplicativo Node.js:
Faça login do usuário com a conta da Apple e receba o token do ID da Apple do usuário. Isso pode ser feito de várias maneiras. Por exemplo, se seu app Node.js tiver um front-end de navegador:
No seu back-end, gere uma string aleatória ("nonce") e calcule o hash SHA256 dela. O nonce é um valor de uso único utilizado para validar uma única ida e volta entre os servidores de back-end e de autenticação da Apple.
Versão 9 para a Web
const crypto = require("crypto"); const string_decoder = require("string_decoder"); // Generate a new random string for each sign-in const generateNonce = (length) => { const decoder = new string_decoder.StringDecoder("ascii"); const buf = Buffer.alloc(length); let nonce = ""; while (nonce.length < length) { crypto.randomFillSync(buf); nonce = decoder.write(buf); } return nonce.substr(0, length); }; const unhashedNonce = generateNonce(10); // SHA256-hashed nonce in hex const hashedNonceHex = crypto.createHash('sha256') .update(unhashedNonce).digest().toString('hex');
Versão 8 para a Web
const crypto = require("crypto"); const string_decoder = require("string_decoder"); // Generate a new random string for each sign-in const generateNonce = function(length) { const decoder = new string_decoder.StringDecoder("ascii"); const buf = Buffer.alloc(length); var nonce = ""; while (nonce.length < length) { crypto.randomFillSync(buf); nonce = decoder.write(buf); } return nonce.substr(0, length); }; const unhashedNonce = generateNonce(10); // SHA256-hashed nonce in hex const hashedNonceHex = crypto.createHash('sha256') .update(unhashedNonce).digest().toString('hex');
Na página de login, especifique o nonce com hash na configuração "Fazer login com a Apple":
<script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script> <div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div> <script> AppleID.auth.init({ clientId: YOUR_APPLE_CLIENT_ID, scope: 'name email', redirectURI: URL_TO_YOUR_REDIRECT_HANDLER, // See the next step. state: '[STATE]', // Optional value that Apple will send back to you // so you can return users to the same context after // they sign in. nonce: HASHED_NONCE // The hashed nonce you generated in the previous step. }); </script>
Receber o token do ID da Apple da resposta do POSTed auth no servidor:
app.post('/redirect', (req, res) => { const savedState = req.cookies.__session; const code = req.body.code; const state = req.body.state; const appleIdToken = req.body.id_token; if (savedState !== state || !code) { res.status(403).send('403: Permission denied'); } else { // Sign in with Firebase using appleIdToken. (See next step). } });
Consulte também Como configurar sua página da Web para fazer login com a Apple.
Depois de receber o token do ID da Apple do usuário, use-o para criar um objeto Credential e, em seguida, faça o login do usuário com a credencial:
Versão 9 para a Web
import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth"; const auth = getAuth(); // Build Firebase credential with the Apple ID token. const provider = new OAuthProvider('apple.com'); const authCredential = provider.credential({ idToken: appleIdToken, rawNonce: unhashedNonce, }); // Sign in with credential form the Apple user. signInWithCredential(auth, authCredential) .then((result) => { // User signed in. }) .catch((error) => { // An error occurred. If error.code == 'auth/missing-or-invalid-nonce', // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. console.log(error); });
Versão 8 para a Web
// Build Firebase credential with the Apple ID token. const provider = new firebase.auth.OAuthProvider('apple.com'); const authCredential = provider.credential({ idToken: appleIdToken, rawNonce: unhashedNonce, }); // Sign in with credential form the Apple user. firebase.auth().signInWithCredential(authCredential) .then((result) => { // User signed in. }) .catch((error) => { // An error occurred. If error.code == 'auth/missing-or-invalid-nonce', // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. console.log(error); });
Próximas etapas
Depois que um usuário faz login pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais, que podem ser o número do telefone, o nome de usuário e a senha ou as informações do provedor de autenticação. Essa nova conta é armazenada como parte do projeto do Firebase e pode ser usada para identificar um usuário em todos os apps do projeto, seja qual for o método de login utilizado.
-
Nos apps, a maneira recomendada de saber o status de autenticação do seu usuário é definindo um observador no objeto
Auth
. É possível, então, receber as informações básicas de perfil do usuário do objetoUser
. Consulte Gerenciar usuários. Nas Regras de segurança do Firebase Realtime Database e do Cloud Storage, é possível receber o ID exclusivo do usuário conectado da variável
auth
e usar esse ID para controlar quais dados um usuário pode acessar.
Os usuários podem fazer login no app usando vários provedores de autenticação. Basta vincular as credenciais desses provedores a uma conta de usuário.
Para desconectar um usuário, chame signOut
:
Versão 9 para a Web
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
Versão 8 para a Web
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });