JavaScript'te E-posta Bağlantısı Kullanarak Firebase ile Kimlik Doğrulama

Kullanıcıya, oturum açmak için tıklayabileceği bir bağlantı içeren e-posta göndererek oturum açmasını sağlamak için Firebase Authentication'ı kullanabilirsiniz. Bu işlem sırasında kullanıcının e-posta adresi de doğrulanır.

E-postayla oturum açmanın birçok avantajı vardır:

  • Kolay kayıt ve oturum açma.
  • Uygulamalarda şifrelerin yeniden kullanılması riskini azaltır. Bu durum, iyi seçilmiş şifrelerin bile güvenliğini zayıflatabilir.
  • Kullanıcıyı kimlik doğrulama ve aynı zamanda kullanıcının bir e-posta adresinin yasal sahibi olduğunu doğrulama özelliği.
  • Kullanıcıların oturum açmak için erişilebilir bir e-posta hesabına sahip olması yeterlidir. Telefon numarası veya sosyal medya hesabı sahipliği gerekmez.
  • Kullanıcı, mobil cihazda zahmetli olabilecek bir şifre girmeden (veya şifreyi hatırlamadan) güvenli bir şekilde oturum açabilir.
  • Daha önce bir e-posta tanımlayıcısıyla (şifre veya federasyon) oturum açmış mevcut bir kullanıcı, yalnızca e-postayla oturum açacak şekilde yükseltilebilir. Örneğin, şifresini unutan bir kullanıcı, şifresini sıfırlamasına gerek kalmadan oturum açmaya devam edebilir.

Başlamadan önce

Henüz yapmadıysanız Firebase konsolundan başlatma snippet'ini Firebase'i JavaScript projenize ekleme bölümünde açıklandığı şekilde projenize kopyalayın.

Kullanıcıların e-posta bağlantısıyla oturum açmasını sağlamak için öncelikle Firebase projenizde e-posta sağlayıcısını ve e-posta bağlantısıyla oturum açma yöntemini etkinleştirmeniz gerekir:

  1. Firebase konsolunda Güvenlik > Kimlik doğrulama'ya gidin.

  2. Oturum açma yöntemi sekmesinde E-posta/Şifre oturum açma yöntemini etkinleştirin. E-posta bağlantısı ile oturum açma özelliğini kullanmak için e-posta/şifre ile oturum açma özelliğinin etkinleştirilmesi gerektiğini unutmayın.

  3. Aynı bölümde, E-posta bağlantısı (şifresiz oturum açma) oturum açma hizmet sağlayıcısını etkinleştirin.

  4. Kaydet'i tıklayın.

Kimlik doğrulama akışını başlatmak için kullanıcıya e-posta adresini girmesini isteyen bir arayüz sunun ve ardından Firebase'in kimlik doğrulama bağlantısını kullanıcının e-posta adresine göndermesini istemek için sendSignInLinkToEmail işlevini çağırın.

  1. Firebase'e e-posta bağlantısının nasıl oluşturulacağıyla ilgili talimatlar sağlayan ActionCodeSettings nesnesini oluşturun. Aşağıdaki alanları ayarlayın:

    • url: Yerleştirilecek derin bağlantı ve iletilecek ek durum. Henüz yapmadıysanız alanınızı yetkili alanlar listesine ekleyin:

      1. Firebase konsolunda Güvenlik > Kimlik doğrulama > Ayarlar sekmesine gidin.

      2. Yetkili alanlar bölümünde Alan ekle'yi tıklayın ve alanınızı ekleyin.

    • android ve ios: Firebase Authentication, yalnızca web'e özel mi yoksa Android veya Apple cihazda açılan mobil bağlantı mı oluşturması gerektiğine karar vermesine yardımcı olur.
    • handleCodeInApp: Doğru olarak ayarlayın. Oturum açma işlemi, bant dışı diğer e-posta işlemlerinin (şifre sıfırlama ve e-posta doğrulamaları) aksine her zaman uygulamada tamamlanmalıdır. Bunun nedeni, akışın sonunda kullanıcının oturum açmış olması ve kimlik doğrulama durumunun uygulamada kalıcı hale getirilmesidir.
    • linkDomain: Bir proje için özel Hosting bağlantı alanları tanımlandığında, bağlantı belirli bir mobil uygulama tarafından açılacaksa hangi alanın kullanılacağını belirtin. Aksi takdirde, varsayılan alan otomatik olarak seçilir (örneğin, PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: Kullanımdan kaldırıldı. Bu parametreyi belirtmeyin.

      Web

      const actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        // The domain must be configured in Firebase Hosting and owned by the project.
        linkDomain: 'custom-domain.com'
      };

      Web

      var actionCodeSettings = {
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be in the authorized domains list in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true.
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.example.ios'
        },
        android: {
          packageName: 'com.example.android',
          installApp: true,
          minimumVersion: '12'
        },
        dynamicLinkDomain: 'example.page.link'
      };

    ActionCodeSettings hakkında daha fazla bilgi edinmek için E-posta İşlemlerinde Durum Geçirme bölümüne bakın.

  2. Kullanıcıdan e-posta adresini isteyin.

  3. Kimlik doğrulama bağlantısını kullanıcının e-posta adresine gönderin ve kullanıcının e-posta ile oturum açma işlemini aynı cihazda tamamlaması ihtimaline karşı e-posta adresini kaydedin.

    Web

    import { getAuth, sendSignInLinkToEmail } from "firebase/auth";
    
    const auth = getAuth();
    sendSignInLinkToEmail(auth, email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        const errorCode = error.code;
        const errorMessage = error.message;
        // ...
      });

    Web

    firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings)
      .then(() => {
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        window.localStorage.setItem('emailForSignIn', email);
        // ...
      })
      .catch((error) => {
        var errorCode = error.code;
        var errorMessage = error.message;
        // ...
      });

Güvenlikle ilgili endişeler

Oturum açma bağlantısının, oturum açma akışı tamamlanırken kullanıcının e-posta adresinin sağlanmasını zorunlu kılarak istenmeyen bir kullanıcı olarak veya istenmeyen bir cihazda oturum açmak için kullanılmasını önler. Oturum açma işleminin başarılı olması için bu e-posta adresinin, oturum açma bağlantısının ilk gönderildiği adresle eşleşmesi gerekir.

Oturum açma e-postasını gönderirken e-posta adreslerini yerel olarak (ör. localStorage veya çerezleri kullanarak) depolayarak oturum açma bağlantısını istedikleri cihazda açan kullanıcılar için bu akışı kolaylaştırabilirsiniz. Ardından, akışı tamamlamak için bu adresi kullanın. Yönlendirme URL'si parametrelerinde kullanıcının e-posta adresini iletmeyin ve oturum ekleme saldırılarına olanak verebileceğinden bunu yeniden kullanmayın.

Oturum açma işlemi tamamlandıktan sonra, daha önce doğrulanmamış tüm oturum açma mekanizmaları kullanıcıdan kaldırılır ve mevcut oturumlar geçersiz kılınır. Örneğin, daha önce aynı e-posta adresi ve şifreyle doğrulanmamış bir hesap oluşturulduysa sahipliği iddia eden ve doğrulanmamış hesabı oluşturan kişinin doğrulanmamış e-posta adresi ve şifreyle tekrar oturum açmasını önlemek için kullanıcının şifresi kaldırılır.

Ayrıca, bağlantınızın aracı sunucular tarafından olası bir şekilde engellenmesini önlemek için üretimde bir HTTPS URL'si kullandığınızdan emin olun.

Web sayfasında oturum açma işlemini tamamlama

E-posta bağlantısı derin bağlantısının biçimi, bant dışı e-posta işlemleri için kullanılan biçimle (e-posta doğrulama, şifre sıfırlama ve e-posta değişikliğini iptal etme) aynıdır. Firebase Auth, isSignInWithEmailLink API'si sağlayarak bu kontrolü basitleştirir. Bu API, bir bağlantının e-posta ile oturum açma bağlantısı olup olmadığını kontrol eder.

Açılış sayfasında oturum açma işlemini tamamlamak için signInWithEmailLink işlevini kullanıcının e-posta adresi ve tek kullanımlık kodu içeren gerçek e-posta bağlantısıyla birlikte çağırın.

Web

import { getAuth, isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth";

// Confirm the link is a sign-in with email link.
const auth = getAuth();
if (isSignInWithEmailLink(auth, window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  let email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  signInWithEmailLink(auth, email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user by importing getAdditionalUserInfo
      // and calling it with result:
      // getAdditionalUserInfo(result)
      // You can access the user's profile via:
      // getAdditionalUserInfo(result)?.profile
      // You can check if the user is new or existing:
      // getAdditionalUserInfo(result)?.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

Web

// Confirm the link is a sign-in with email link.
if (firebase.auth().isSignInWithEmailLink(window.location.href)) {
  // Additional state parameters can also be passed via URL.
  // This can be used to continue the user's intended action before triggering
  // the sign-in operation.
  // Get the email if available. This should be available if the user completes
  // the flow on the same device where they started it.
  var email = window.localStorage.getItem('emailForSignIn');
  if (!email) {
    // User opened the link on a different device. To prevent session fixation
    // attacks, ask the user to provide the associated email again. For example:
    email = window.prompt('Please provide your email for confirmation');
  }
  // The client SDK will parse the code from the link for you.
  firebase.auth().signInWithEmailLink(email, window.location.href)
    .then((result) => {
      // Clear email from storage.
      window.localStorage.removeItem('emailForSignIn');
      // You can access the new user via result.user
      // Additional user info profile not available via:
      // result.additionalUserInfo.profile == null
      // You can check if the user is new or existing:
      // result.additionalUserInfo.isNewUser
    })
    .catch((error) => {
      // Some error occurred, you can inspect the code: error.code
      // Common errors could be invalid email and invalid or expired OTPs.
    });
}

Mobil uygulamada oturum açma işlemini tamamlama

Firebase Authentication, e-posta bağlantısını mobil cihaza göndermek için Firebase Hosting kullanır. Mobil uygulama üzerinden oturum açma işleminin tamamlanması için uygulamanın gelen uygulama bağlantısını algılayacak, temel derin bağlantıyı ayrıştıracak ve ardından oturum açma işlemini web akışında olduğu gibi tamamlayacak şekilde yapılandırılması gerekir.

Android uygulamasında e-posta bağlantısıyla oturum açma işlemini yönetme hakkında daha fazla bilgi edinmek için Android kılavuzuna bakın.

Apple uygulamasında e-posta bağlantısıyla oturum açma işlemini nasıl yapacağınız hakkında daha fazla bilgi edinmek için Apple platformları kılavuzuna bakın.

Bu kimlik doğrulama yöntemini mevcut bir kullanıcıya da bağlayabilirsiniz. Örneğin, daha önce telefon numarası gibi başka bir sağlayıcıyla kimlik doğrulaması yapmış bir kullanıcı, bu oturum açma yöntemini mevcut hesabına ekleyebilir.

Fark, işlemin ikinci yarısında ortaya çıkar:

Web

import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
const auth = getAuth();
linkWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

Web

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Link the credential to the current user.
firebase.auth().currentUser.linkWithCredential(credential)
  .then((usercred) => {
    // The provider is now successfully linked.
    // The phone user can now sign in with their phone number or email.
  })
  .catch((error) => {
    // Some error occurred.
  });

Bu özellik, hassas bir işlem gerçekleştirilmeden önce e-posta bağlantısı kullanıcısının kimliğini yeniden doğrulamak için de kullanılabilir.

Web

import { getAuth, reauthenticateWithCredential, EmailAuthProvider } from "firebase/auth";

// Construct the email link credential from the current URL.
const credential = EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
const auth = getAuth();
reauthenticateWithCredential(auth.currentUser, credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

Web

// Construct the email link credential from the current URL.
var credential = firebase.auth.EmailAuthProvider.credentialWithLink(
  email, window.location.href);

// Re-authenticate the user with this credential.
firebase.auth().currentUser.reauthenticateWithCredential(credential)
  .then((usercred) => {
    // The user is now successfully re-authenticated and can execute sensitive
    // operations.
  })
  .catch((error) => {
    // Some error occurred.
  });

Ancak akış, orijinal kullanıcının oturum açmadığı farklı bir cihazda sonlanabileceğinden bu akış tamamlanmayabilir. Bu durumda, kullanıcıya bağlantıyı aynı cihazda açmasını zorunlu kılmak için bir hata gösterilebilir. İşlemin türü ve kullanıcı kimliği hakkında bilgi sağlamak için bağlantıda bazı durumlar aktarılabilir.

Projenizi 15 Eylül 2023'te veya sonrasında oluşturduysanız e-posta numaralandırması koruması varsayılan olarak etkindir. Bu özellik, projenizin kullanıcı hesaplarının güvenliğini artırır ancak daha önce tanımlayıcı öncelikli akışları uygulamak için önerdiğimiz fetchSignInMethodsForEmail() yöntemini devre dışı bırakır.

Projeniz için e-posta numaralandırma korumasını devre dışı bırakabilirsiniz ancak bunu yapmamanızı öneririz.

Daha fazla ayrıntı için e-posta numaralandırma koruması ile ilgili dokümanları inceleyin.

Bağlantı ile oturum açma için varsayılan e-posta şablonu

Varsayılan e-posta şablonu, konu ve e-posta mesajına zaman damgası ekler. Böylece sonraki e-postalar tek bir ileti dizisinde daraltılmaz ve bağlantı gizlenmez.

Bu şablon aşağıdaki dillerde geçerlidir:

Kod Dil
ar Arapça
zh-CN Çince (Basitleştirilmiş)
zh-TW Çince (Geleneksel)
nl Felemenkçe
en İngilizce
en-GB İngilizce (İngiltere)
fr Fransızca
de Almanca
id Endonezce
it İtalyanca
ja Japonca
ko Korece
pl Lehçe
pt-BR Portekizce (Brezilya)
pt-PT Portekizce (Portekiz)
ru Rusça
es İspanyolca
es-419 İspanyolca (Latin Amerika)
th Tayca

Sonraki adımlar

Bir kullanıcı ilk kez oturum açtıktan sonra yeni bir kullanıcı hesabı oluşturulur ve kullanıcının oturum açtığı kimlik bilgilerine (kullanıcı adı ve şifre, telefon numarası veya kimlik doğrulama sağlayıcı bilgileri) bağlanır. Bu yeni hesap, Firebase projenizin bir parçası olarak depolanır ve kullanıcının nasıl oturum açtığına bakılmaksızın projenizdeki her uygulamada kullanıcıyı tanımlamak için kullanılabilir.

  • Uygulamalarınızda, kullanıcınızın kimlik doğrulama durumunu öğrenmenin önerilen yolu, Auth nesnesinde bir gözlemci ayarlamaktır. Ardından, User nesnesinden kullanıcının temel profil bilgilerini alabilirsiniz. Kullanıcıları yönetme başlıklı makaleyi inceleyin.

  • Firebase Realtime Database ve Cloud Storage Güvenlik Kurallarınızda, oturum açmış kullanıcının benzersiz kullanıcı kimliğini auth değişkeninden alabilir ve kullanıcının hangi verilere erişebileceğini kontrol etmek için bu kimliği kullanabilirsiniz.

Kimlik doğrulama sağlayıcı kimlik bilgilerini mevcut bir kullanıcı hesabına bağlayarak kullanıcıların uygulamanızda birden fazla kimlik doğrulama sağlayıcı kullanarak oturum açmasına izin verebilirsiniz.

Bir kullanıcının oturumunu kapatmak için signOut numaralı telefonu arayın:

Web

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});