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

Firebase Authentication'i kullanarak kullanıcılara oturum açmaları için tıklayabilecekleri bir bağlantı içeren bir e-posta gönderebilirsiniz. Bu süreçte kullanıcının e-posta adresi de doğrulanır.

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

  • Kolay kayıt ve oturum açma.
  • Uygulamalar arasında şifrelerin yeniden kullanılması riskini azaltır. Bu risk, iyi seçilmiş şifrelerin güvenliğini bile tehlikeye atabilir.
  • Bir kullanıcının kimliğini doğrularken aynı zamanda e-posta adresinin gerçek sahibi olduğunu doğrulama olanağı.
  • 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ına sahip olmanız gerekmez.
  • Kullanıcı, mobil cihazlarda zahmetli olabilecek şifre girmek (veya hatırlamak) zorunda kalmadan güvenli bir şekilde oturum açabilir.
  • Daha önce e-posta tanımlayıcısı (şifre veya birleşik) ile oturum açmış mevcut bir kullanıcının oturum açma yöntemi, yalnızca e-posta ile oturum açacak şekilde yükseltilebilir. Örneğin, şifresini unutmuş bir kullanıcı, şifresini sıfırlamak zorunda kalmadan oturum açabilir.

Başlamadan önce

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

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

  1. Firebase konsolunda Auth bölümünü açın.
  2. Oturum açma yöntemi sekmesinde E-posta/Şifre sağlayıcısını etkinleştirin. E-posta bağlantısıyla oturum açma özelliğini kullanabilmek için e-posta/şifre ile oturum açma özelliğinin etkinleştirilmiş olması gerekir.
  3. Aynı bölümde, E-posta bağlantısı (şifresiz oturum açma) oturum açma yöntemini 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 gösterin ve ardından sendSignInLinkToEmail işlevini çağırarak Firebase'ın kimlik doğrulama bağlantısını kullanıcının e-postasına göndermesini isteyin.

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

    • url: Yerleştirilecek derin bağlantı ve iletilecek ek durum. Bağlantının alanının, Oturum açma yöntemi sekmesine (Kimlik doğrulama -> Ayarlar) giderek bulabileceğiniz Firebase Console'daki yetkili alanlar listesine eklenmesi gerekir.
    • android ve ios: Firebase Authentication'nin, Android veya Apple cihazda açılan yalnızca web bağlantısı mı yoksa mobil bağlantı mı oluşturacağını belirlemesine yardımcı olur.
    • handleCodeInApp: Doğru olarak ayarlanır. Diğer bant dışı e-posta işlemlerinden (şifre sıfırlama ve e-posta doğrulamaları) farklı olarak oturum açma işleminin her zaman uygulamada tamamlanması gerekir. Bunun nedeni, akışın sonunda kullanıcının oturum açmış olması ve kimlik doğrulama durumunun uygulamada devam etmesidir.
    • linkDomain: Bir proje için özel Hosting bağlantı alanları tanımlandığında, bağlantı belirli bir mobil uygulama tarafından açıldığında hangi alanın kullanılacağını belirtin. Aksi takdirde varsayılan alan otomatik olarak seçilir (örneğin, PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: Desteği sonlandı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'
        },
        dynamicLinkDomain: 'example.page.link'
      };

      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ünü inceleyin.

  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 oturumunu aynı cihazda tamamlaması ihtimaline karşı kullanıcının 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 sorunlar

Bir oturum açma bağlantısının, istenmeyen bir kullanıcı olarak veya istenmeyen bir cihazda oturum açmak için kullanılmasını önlemek amacıyla Firebase Auth, oturum açma akışı tamamlanırken kullanıcının e-posta adresinin sağlanmasını zorunlu kılar. Oturum açmanın başarılı olması için bu e-posta adresinin, oturum açma bağlantısının orijinal olarak gönderildiği adresle eşleşmesi gerekir.

Oturum açma e-postasını gönderirken e-posta adreslerini yerel olarak depolayarak (ör. localStorage veya çerezleri kullanarak) oturum açma bağlantısını isteklerini gönderdikleri cihazda açan kullanıcılar için bu akışı kolaylaştırabilirsiniz. Ardından, akışı tamamlamak için bu adresi kullanın. Kullanıcının e-posta adresini yönlendirme URL'si parametrelerine iletmeyin ve yeniden kullanmayın. Aksi takdirde oturum ekleme işlemleri etkinleştirilebilir.

Oturum açma işlemi tamamlandıktan sonra, daha önce doğrulanmamış 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 ve şifreyle doğrulanmamış bir hesap oluşturan bir kullanıcının şifresi, sahiplik iddiasında bulunan ve doğrulanmamış hesabı oluşturan kimliğe bürünen kişinin doğrulanmamış e-posta ve şifreyle tekrar oturum açmasını önlemek için kaldırılır.

Ayrıca, bağlantınızın aracı sunucularca kesilmesi ihtimalini önlemek için üretimde HTTPS URL'si kullandığınızdan emin olun.

Bir 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çim (e-posta doğrulaması, şifre sıfırlama ve e-posta değişikliğinin iptal edilmesi) ile aynıdır. Firebase Auth, bir bağlantının e-posta ile oturum açma bağlantısı olup olmadığını kontrol etmek için isSignInWithEmailLink API'yi sağlayarak bu kontrolü basitleştirir.

Açılış sayfasında oturum açmayı tamamlamak için kullanıcının e-posta adresini ve tek kullanımlık kodu içeren gerçek e-posta bağlantısını kullanarak signInWithEmailLink numaralı telefonu arayı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'u kullanır. Mobil uygulama üzerinden oturum açmanın tamamlanması için uygulamanın, gelen uygulama bağlantısını algılayacak, temel derin bağlantıyı ayrıştıracak ve ardından oturumu web akışı üzerinden yapıldığı gibi tamamlayacak şekilde yapılandırılması gerekir.

Android uygulamasında e-posta bağlantısıyla oturum açma özelliğini kullanma 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 özelliğini kullanma 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 kimliğini doğrulayan 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 yöntem, hassas bir işlem yapmadan ö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 sona erebileceğinden bu akış tamamlanamayabilir. Bu durumda, kullanıcıya bağlantıyı aynı cihazda açmaya zorlamak için bir hata gösterilebilir. İşlemin türü ve kullanıcı kimliği hakkında bilgi sağlamak için bağlantıya bazı durum bilgileri iletilebilir.

Projenizi 15 Eylül 2023'te veya sonrasında oluşturduysanız e-posta numaralandırma 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ı oturumu açma için varsayılan e-posta şablonu

Varsayılan e-posta şablonu, konu ve e-posta gövdesinde bir zaman damgası içerir. Böylece sonraki e-postalar tek bir ileti dizisine daraltılmaz ve bağlantı gizlenir.

Bu şablon aşağıdaki diller için 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)
. Tayca

Sonraki adımlar

Kullanıcı ilk kez oturum açtıktan sonra yeni bir kullanıcı hesabı oluşturulur ve kullanıcının oturum açarken kullandığı kimlik bilgilerine (yani 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 nesnesine bir gözlemci ayarlamaktır. Ardından, kullanıcının temel profil bilgilerini User nesnesinden 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 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:

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.
});