Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Autenticare con Firebase utilizzando il collegamento e-mail in Android

È possibile utilizzare l'autenticazione Firebase per accedere a un utente inviando loro un'e-mail contenente un collegamento, a cui possono fare clic per accedere. Nel processo, viene verificato anche l'indirizzo e-mail dell'utente.

Esistono numerosi vantaggi per l'accesso tramite e-mail:

  • Iscrizione e accesso a basso attrito.
  • Riduzione del rischio di riutilizzo delle password tra le applicazioni, che può compromettere la sicurezza anche di password ben selezionate.
  • La possibilità di autenticare un utente verificando al contempo che l'utente sia il legittimo proprietario di un indirizzo e-mail.
  • Per accedere è necessario solo un account di posta elettronica accessibile. Non è richiesta la proprietà di un numero di telefono o di un account di social media.
  • Un utente può accedere in modo sicuro senza la necessità di fornire (o ricordare) una password, che può essere ingombrante su un dispositivo mobile.
  • Un utente esistente che in precedenza ha effettuato l'accesso con un identificativo e-mail (password o federato) può essere aggiornato per accedere solo tramite e-mail. Ad esempio, un utente che ha dimenticato la password può ancora accedere senza dover reimpostare la password.

Prima di iniziare

Configura il tuo progetto Android

  1. Se non lo hai già fatto, aggiungi Firebase al tuo progetto Android .
  2. Nel file build.gradle livello di build.gradle , assicurati di includere il repository Maven di Google nelle sezioni buildscript e allprojects .
  3. Aggiungi le dipendenze per la libreria Android di Firebase Authentication e i servizi Google Play al tuo modulo (a livello di app) File Gradle (di solito app/build.gradle ):

     implementation 'com.google.firebase:firebase-auth:19.3.2'
    implementation 'com.google.android.gms:play-services-auth:18.1.0'
     

Per accedere agli utenti tramite collegamento e-mail, è innanzitutto necessario abilitare il provider di posta elettronica e il metodo di accesso al collegamento e-mail per il progetto Firebase:

  1. Nella console di Firebase , apri la sezione Auth .
  2. Nella scheda Metodo di accesso , abilitare il provider Email / Password . Si noti che l'accesso e-mail / password deve essere abilitato per utilizzare l'accesso al collegamento e-mail.
  3. Nella stessa sezione, abilitare il metodo di accesso Collegamento e-mail (accesso senza password) .
  4. Fai clic su Salva .

Per avviare il flusso di autenticazione, presentare all'utente un'interfaccia che richiede all'utente di fornire il proprio indirizzo e-mail e quindi chiamare sendSignInLinkToEmail per richiedere a Firebase di inviare il collegamento di autenticazione al messaggio di posta elettronica dell'utente.

  1. Costruisci l'oggetto ActionCodeSettings , che fornisce a Firebase le istruzioni su come costruire il link e-mail. Imposta i seguenti campi:

    • url : il collegamento diretto da incorporare e qualsiasi stato aggiuntivo da trasmettere. Il dominio del collegamento deve essere autorizzato nell'elenco dei domini autorizzati Firebase Console, che può essere trovato andando nella scheda Metodo di accesso (Autenticazione -> Metodo di accesso). Il collegamento reindirizzerà l'utente a questo URL se l'app non è installata sul proprio dispositivo e l'app non è stata installata.
    • androidPackageName e IOSBundleId : le app da utilizzare quando si apre il collegamento di accesso su un dispositivo Android o iOS. Ulteriori informazioni su come configurare i collegamenti dinamici Firebase per aprire collegamenti di azioni e-mail tramite app mobili.
    • handleCodeInApp : impostato su true. L'operazione di accesso deve sempre essere completata nell'app a differenza di altre azioni e-mail fuori banda (reimpostazione password e verifiche e-mail). Questo perché, al termine del flusso, si prevede che l'utente abbia effettuato l'accesso e che il suo stato Auth sia persistito all'interno dell'app.
    • dynamicLinkDomain : quando vengono definiti più domini di collegamento dinamico personalizzati per un progetto, specificare quale utilizzare quando si deve aprire il collegamento tramite un'app mobile specificata (ad esempio example.page.link ). Altrimenti il ​​primo dominio viene automaticamente selezionato.

    Giava

    ActionCodeSettings actionCodeSettings =
            ActionCodeSettings.newBuilder()
                    // URL you want to redirect back to. The domain (www.example.com) for this
                    // URL must be whitelisted in the Firebase Console.
                    .setUrl("https://www.example.com/finishSignUp?cartId=1234")
                    // This must be true
                    .setHandleCodeInApp(true)
                    .setIOSBundleId("com.example.ios")
                    .setAndroidPackageName(
                            "com.example.android",
                            true, /* installIfNotAvailable */
                            "12"    /* minimumVersion */)
                    .build();

    Kotlin + KTX

    val actionCodeSettings = actionCodeSettings {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url = "https://www.example.com/finishSignUp?cartId=1234"
        // This must be true
        handleCodeInApp = true
        iosBundleId = "com.example.ios"
        setAndroidPackageName(
                "com.example.android",
                true, /* installIfNotAvailable */
                "12" /* minimumVersion */)
    }

    Per ulteriori informazioni su ActionCodeSettings, consultare la sezione Stato di passaggio nelle azioni e-mail .

  2. Chiedi all'utente la sua email.

  3. Invia il link di autenticazione all'e-mail dell'utente e salva l'e-mail dell'utente nel caso in cui l'utente completi l'accesso e-mail sullo stesso dispositivo.

    Giava

    FirebaseAuth auth = FirebaseAuth.getInstance();
    auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Email sent.");
                    }
                }
            });

    Kotlin + KTX

    Firebase.auth.sendSignInLinkToEmail(email, actionCodeSettings)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Email sent.")
                }
            }

Problemi di sicurezza

Per impedire che un collegamento di accesso venga utilizzato per accedere come utente non intenzionale o su un dispositivo non intenzionale, Firebase Auth richiede che l'indirizzo e-mail dell'utente sia fornito al completamento del flusso di accesso. Perché l'accesso abbia esito positivo, questo indirizzo e-mail deve corrispondere all'indirizzo a cui è stato originariamente inviato il collegamento di accesso.

È possibile semplificare questo flusso per gli utenti che aprono il collegamento di accesso sullo stesso dispositivo che richiedono il collegamento, memorizzando il proprio indirizzo e-mail localmente, ad esempio utilizzando SharedPreferences, quando si invia l'e-mail di accesso. Quindi, utilizzare questo indirizzo per completare il flusso. Non passare l'e-mail dell'utente nei parametri dell'URL di reindirizzamento e riutilizzarla in quanto ciò potrebbe consentire iniezioni di sessione.

Dopo il completamento dell'accesso, qualsiasi precedente meccanismo di accesso non verificato verrà rimosso dall'utente e tutte le sessioni esistenti verranno invalidate. Ad esempio, se qualcuno ha precedentemente creato un account non verificato con la stessa e-mail e la stessa password, la password dell'utente verrà rimossa per impedire al sosia che ha rivendicato la proprietà e creato l'account non verificato di accedere nuovamente con e-mail e password non verificate.

Assicurati inoltre di utilizzare un URL HTTPS in produzione per evitare che il tuo collegamento venga potenzialmente intercettato dai server intermedi.

Completamento dell'accesso in un'app Android

L'autenticazione Firebase utilizza i collegamenti dinamici Firebase per inviare il collegamento e-mail a un dispositivo mobile. Per il completamento dell'accesso tramite l'applicazione mobile, l'applicazione deve essere configurata per rilevare il collegamento dell'applicazione in arrivo, analizzare il collegamento diretto sottostante e quindi completare l'accesso.

Firebase Auth utilizza i collegamenti dinamici Firebase durante l'invio di un collegamento che si intende aprire in un'applicazione mobile. Per utilizzare questa funzione, i collegamenti dinamici devono essere configurati in Firebase Console.

  1. Abilita collegamenti dinamici Firebase:

    1. Nella console di Firebase , apri la sezione Collegamenti dinamici .
    2. Se non hai ancora accettato i termini di collegamenti dinamici e hai creato un dominio di collegamenti dinamici, fallo ora.

      Se hai già creato un dominio Dynamic Link, prendine nota. Un dominio Dynamic Links si presenta in genere come nell'esempio seguente:

      example.page.link

      Sarà necessario questo valore quando si configura l'app iOS o Android per intercettare il collegamento in entrata.

  2. Configurazione di applicazioni Android:

    1. Per gestire questi collegamenti dall'applicazione Android, è necessario specificare il nome del pacchetto Android nelle impostazioni del progetto Console Firebase. Inoltre, è necessario fornire SHA-1 e SHA-256 del certificato dell'applicazione.
    2. Ora che hai aggiunto un dominio di collegamento dinamico e assicurato che l'app Android sia configurata correttamente, il collegamento dinamico verrà reindirizzato alla tua applicazione, a partire dall'attività di avvio.
    3. Se desideri che il collegamento dinamico venga reindirizzato a un'attività specifica, dovrai configurare un filtro intenti nel tuo file AndroidManifest.xml . Questo può essere fatto specificando il dominio del collegamento dinamico o il gestore dell'azione e-mail nel filtro intento. Per impostazione predefinita, il gestore di azioni e-mail è ospitato su un dominio come nell'esempio seguente:
       PROJECT_ID .firebaseapp.com/
    4. Avvertenze:
      1. Non specificare l'URL impostato su actionCodeSettings nel filtro intenti.
      2. Durante la creazione del dominio di collegamento dinamico è possibile che sia stato creato anche un breve collegamento URL. Questo breve URL non verrà passato; non configurare il filtro di intenti per catturarlo con un attributo android:pathPrefix . Ciò significa che non sarai in grado di catturare diversi collegamenti dinamici in diverse parti dell'applicazione. Tuttavia, è possibile controllare il parametro della query in mode nel collegamento per vedere quale operazione sta tentando di eseguire oppure utilizzare metodi SDK come isSignInWithEmailLink per vedere se un collegamento ricevuto dalla propria app fa quello che si desidera.
    5. Per ulteriori informazioni sulla ricezione di collegamenti dinamici, consultare le istruzioni per la ricezione di collegamenti dinamici Android .

Dopo aver ricevuto il collegamento come descritto sopra, verificare che sia destinato all'autenticazione del collegamento e-mail e completare l'accesso.

Giava

FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    String email = "someemail@domain.com";

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Successfully signed in with email link!");
                        AuthResult result = task.getResult();
                        // You can access the new user via result.getUser()
                        // Additional user info profile *not* available via:
                        // result.getAdditionalUserInfo().getProfile() == null
                        // You can check if the user is new or existing:
                        // result.getAdditionalUserInfo().isNewUser()
                    } else {
                        Log.e(TAG, "Error signing in with email link", task.getException());
                    }
                }
            });
}

Kotlin + KTX

val auth = Firebase.auth
val intent = intent
val emailLink = intent.data.toString()

// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
    // Retrieve this from wherever you stored it
    val email = "someemail@domain.com"

    // The client SDK will parse the code from the link for you.
    auth.signInWithEmailLink(email, emailLink)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "Successfully signed in with email link!")
                    val result = task.result
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error signing in with email link", task.exception)
                }
            }
}

Per ulteriori informazioni su come gestire l'accesso con collegamento e-mail in un'applicazione iOS, consultare la guida iOS .

Per informazioni su come gestire l'accesso con il collegamento e-mail in un'applicazione Web, consultare la Guida Web .

Puoi anche collegare questo metodo di autenticazione a un utente esistente. Ad esempio, un utente precedentemente autenticato con un altro provider, ad esempio un numero di telefono, può aggiungere questo metodo di accesso al proprio account esistente.

La differenza sarebbe nella seconda metà dell'operazione:

Giava

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Link the credential to the current user.
auth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Successfully linked emailLink credential!");
                    AuthResult result = task.getResult();
                    // You can access the new user via result.getUser()
                    // Additional user info profile *not* available via:
                    // result.getAdditionalUserInfo().getProfile() == null
                    // You can check if the user is new or existing:
                    // result.getAdditionalUserInfo().isNewUser()
                } else {
                    Log.e(TAG, "Error linking emailLink credential", task.getException());
                }
            }
        });

Kotlin + KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Link the credential to the current user.
Firebase.auth.currentUser!!.linkWithCredential(credential)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                Log.d(TAG, "Successfully linked emailLink credential!")
                val result = task.result
                // You can access the new user via result.getUser()
                // Additional user info profile *not* available via:
                // result.getAdditionalUserInfo().getProfile() == null
                // You can check if the user is new or existing:
                // result.getAdditionalUserInfo().isNewUser()
            } else {
                Log.e(TAG, "Error linking emailLink credential", task.exception)
            }
        }

Questo può anche essere usato per autenticare nuovamente un utente di collegamento e-mail prima di eseguire un'operazione sensibile.

Giava

// Construct the email link credential from the current URL.
AuthCredential credential =
        EmailAuthProvider.getCredentialWithLink(email, emailLink);

// Re-authenticate the user with this credential.
auth.getCurrentUser().reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // User is now successfully reauthenticated
                } else {
                    Log.e(TAG, "Error reauthenticating", task.getException());
                }
            }
        });

Kotlin + KTX

// Construct the email link credential from the current URL.
val credential = EmailAuthProvider.getCredentialWithLink(email, emailLink)

// Re-authenticate the user with this credential.
Firebase.auth.currentUser!!.reauthenticateAndRetrieveData(credential)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // User is now successfully reauthenticated
            } else {
                Log.e(TAG, "Error reauthenticating", task.exception)
            }
        }

Tuttavia, poiché il flusso potrebbe finire su un dispositivo diverso in cui l'utente originale non era connesso, questo flusso potrebbe non essere completato. In tal caso, è possibile mostrare all'utente un errore per costringerli ad aprire il collegamento sullo stesso dispositivo. È possibile passare un certo stato nel collegamento per fornire informazioni sul tipo di operazione e sull'utente uid.

Nel caso in cui supporti sia l'accesso basato su password che su collegamento con e-mail, per differenziare il metodo di accesso per un utente password / collegamento, usa fetchSignInMethodsForEmail . Ciò è utile per i flussi identificativi per primi in cui all'utente viene chiesto per primo di fornire la propria e-mail e quindi presentato il metodo di accesso:

Giava

auth.fetchSignInMethodsForEmail(email)
        .addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
            @Override
            public void onComplete(@NonNull Task<SignInMethodQueryResult> task) {
                if (task.isSuccessful()) {
                    SignInMethodQueryResult result = task.getResult();
                    List<String> signInMethods = result.getSignInMethods();
                    if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                        // User can sign in with email/password
                    } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                        // User can sign in with email/link
                    }
                } else {
                    Log.e(TAG, "Error getting sign in methods for user", task.getException());
                }
            }
        });

Kotlin + KTX

Firebase.auth.fetchSignInMethodsForEmail(email)
        .addOnSuccessListener { result ->
            val signInMethods = result.signInMethods!!
            if (signInMethods.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD)) {
                // User can sign in with email/password
            } else if (signInMethods.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD)) {
                // User can sign in with email/link
            }
        }
        .addOnFailureListener { exception ->
            Log.e(TAG, "Error getting sign in methods for user", exception)
        }

Come descritto sopra, email / password e email / link sono considerati lo stesso EmailAuthProvider (stesso PROVIDER_ID ) con diversi metodi di accesso.

Prossimi passi

Dopo che un utente accede per la prima volta, viene creato un nuovo account utente e collegato alle credenziali, ovvero nome utente e password, numero di telefono o informazioni del provider di autenticazione, con cui l'utente ha effettuato l'accesso. Questo nuovo account viene archiviato come parte del progetto Firebase e può essere utilizzato per identificare un utente in ogni app del progetto, indipendentemente da come l'utente accede.

  • Nelle tue app puoi ottenere le informazioni di base sul profilo dell'utente dall'oggetto FirebaseUser . Vedi Gestisci utenti .

  • Nelle regole di sicurezza di Firebase Realtime Database e Cloud Storage, è possibile ottenere l'ID utente univoco dell'utente connesso dalla variabile auth e utilizzarlo per controllare i dati a cui un utente può accedere.

Puoi consentire agli utenti di accedere alla tua app utilizzando più provider di autenticazione collegando le credenziali del provider di autenticazione a un account utente esistente.

Per disconnettere un utente, chiama signOut :

Giava

FirebaseAuth.getInstance().signOut();

Kotlin + KTX

Firebase.auth.signOut()