JavaScript Kullanarak Telefon Numarasıyla Firebase ile Kimlik Doğrulama

Firebase Authentication'ı kullanarak kullanıcının telefonuna SMS mesajı göndererek kullanıcının oturumunu açabilirsiniz. Kullanıcı, SMS mesajında yer alan tek kullanımlık bir kodu kullanarak oturum açar.

Uygulamanıza telefon numarası ile oturum açma özelliği eklemenin en kolay yolu, telefon numarasıyla oturum açma için oturum açma akışlarının yanı sıra şifre tabanlı ve birleşik oturum açma özelliğini uygulayan bir açılır oturum açma widget'ı içeren FirebaseUI kullanmaktır. Bu belgede, Firebase SDK'sını kullanarak telefon numarası oturum açma akışının nasıl uygulanacağı açıklanmaktadır.

Başlamadan önce

Henüz yapmadıysanız Firebase'i JavaScript projenize ekleme bölümünde açıklandığı gibi, ilk kullanıma hazırlama snippet'ini Firebase konsolundan projenize kopyalayın.

Güvenlikle ilgili sorunlar

Yalnızca telefon numarası kullanarak yapılan kimlik doğrulama işlemi pratik olan diğer yöntemlere göre daha az güvenlidir. Bunun nedeni, telefon numarasına sahip olma durumunun kullanıcılar arasında kolayca aktarılmasıdır. Ayrıca, birden fazla kullanıcı profiline sahip cihazlarda SMS mesajı alabilen tüm kullanıcılar, cihazın telefon numarasını kullanarak bir hesapta oturum açabilir.

Uygulamanızda telefon numarası tabanlı oturum açma özelliğini kullanıyorsanız bu özelliği daha güvenli oturum açma yöntemleriyle birlikte sunmalı ve kullanıcıları telefon numarasıyla oturum açmanın güvenlik açısından olumsuzlukları hakkında bilgilendirmelisiniz.

Firebase projeniz için Telefon Numarasıyla oturum açmayı etkinleştirme

Kullanıcıların SMS ile oturum açmasını sağlamak için önce Firebase projenizde Telefon Numarası oturum açma yöntemini etkinleştirmeniz gerekir:

  1. Firebase konsolunda Kimlik Doğrulama bölümünü açın.
  2. Oturum Açma Yöntemi sayfasında, Telefon Numarası oturum açma yöntemini etkinleştirin.
  3. Aynı sayfada, uygulamanızı barındıracak alan adı OAuth yönlendirme alanları bölümünde yer almıyorsa alan adınızı ekleyin.

Firebase'in telefon numarası oturum açma isteği kotası, çoğu uygulamanın etkilenmeyecek kadar yüksek. Ancak telefonla kimlik doğrulamayla çok sayıda kullanıcının oturumunu açmanız gerekiyorsa fiyatlandırma planınızı yükseltmeniz gerekebilir. Fiyatlandırma sayfasını inceleyin.

reCAPTCHA doğrulayıcıyı ayarlama

Kullanıcıların telefon numaralarıyla oturum açmasını sağlamadan önce Firebase'in reCAPTCHA doğrulayıcısını ayarlamanız gerekir. Firebase, kötüye kullanımı önlemek için reCAPTCHA'yı kullanır. Örneğin, telefon numarası doğrulama isteğinin uygulamanızın izin verilen alanlarından birinden gelmesini sağlar.

Manuel olarak reCAPTCHA istemcisi ayarlamanıza gerek yoktur. Firebase SDK'sının RecaptchaVerifier nesnesini kullandığınızda Firebase, gerekli istemci anahtarlarını ve gizli anahtarları otomatik olarak oluşturup işler.

RecaptchaVerifier nesnesi, genellikle herhangi bir kullanıcı işlemi gerektirmeden kullanıcıyı doğrulayabilen görünmez reCAPTCHA'nın yanı sıra, işlemin başarıyla tamamlanması için her zaman kullanıcı etkileşimi gerektiren reCAPTCHA widget'ını destekler.

Temel oluşturulan reCAPTCHA, reCAPTCHA oluşturulmadan önce Auth örneğindeki dil kodu güncellenerek kullanıcının tercihine göre yerelleştirilebilir. Yukarıda belirtilen yerelleştirme, kullanıcıya gönderilen ve doğrulama kodunu içeren SMS mesajı için de geçerli olur.

Web modüler API

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// auth.useDeviceLanguage();

Web ad alanı API'si

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Görünmez reCAPTCHA'yı kullan

Görünmez bir reCAPTCHA kullanmak için size parametresi invisible olarak ayarlanmış ve oturum açma formunuzu gönderen düğmenin kimliğini belirterek bir RecaptchaVerifier nesnesi oluşturun. Örnek:

Web modüler API

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

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Web ad alanı API'si

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

reCAPTCHA widget'ını kullanma

Görünür reCAPTCHA widget'ını kullanmak için sayfanızda widget'ı içerecek bir öğe oluşturun. Ardından, kapsayıcının kimliğini belirterek bir RecaptchaVerifier nesnesi oluşturun. Örneğin:

Web modüler API

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

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});

Web ad alanı API'si

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

İsteğe bağlı: reCAPTCHA parametrelerini belirtin

İsteğe bağlı olarak, kullanıcı reCAPTCHA'yı çözdüğünde veya kullanıcı formu göndermeden önce reCAPTCHA'nın süresi dolduğunda RecaptchaVerifier nesnesinde geri çağırma işlevleri ayarlayabilirsiniz:

Web modüler API

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

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Web ad alanı API'si

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

İsteğe bağlı: reCAPTCHA'yı önceden oluşturma

Oturum açma isteği göndermeden önce reCAPTCHA'yı önceden oluşturmak isterseniz render numaralı telefonu arayın:

Web modüler API

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web ad alanı API'si

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

render sorunu çözüldükten sonra reCAPTCHA'nın widget kimliğini alırsınız. Bu widget'ı reCAPTCHA API'sine çağrı yapmak için kullanabilirsiniz:

Web modüler API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web ad alanı API'si

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Kullanıcının telefonuna doğrulama kodu gönderme

Telefon numarasıyla oturum açmayı başlatmak için kullanıcıya telefon numarasını girmesini isteyen bir arayüz sunun. Ardından signInWithPhoneNumber numaralı telefonu arayarak Firebase'in kullanıcının telefonuna SMS ile kimlik doğrulama kodu göndermesini isteyin:

  1. Kullanıcının telefon numarasını alın.

    Yasal şartlar değişiklik gösterir, ancak en iyi uygulama olarak ve kullanıcılarınızın beklentilerini belirlemek amacıyla, telefonla oturum açmalarını kullandıkları takdirde doğrulama için bir SMS mesajı alabileceklerini ve standart ücretlerin geçerli olacağını bildirmeniz gerekir.

  2. Kullanıcının telefon numarasını ve daha önce oluşturduğunuz RecaptchaVerifier bilgisini ileterek signInWithPhoneNumber numaralı telefonu arayın.

    Web modüler API

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web ad alanı API'si

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    signInWithPhoneNumber sonucunda hata oluşursa kullanıcının tekrar deneyebilmesi için reCAPTCHA'yı sıfırlayın:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

signInWithPhoneNumber yöntemi, kullanıcıya reCAPTCHA sorgulaması gönderir ve kullanıcı bu sorgulamayı geçerse Firebase Authentication'ın kullanıcının telefonuna doğrulama kodu içeren bir SMS mesajı göndermesini ister.

Doğrulama koduyla kullanıcının oturumunu açma

signInWithPhoneNumber numaralı telefona yapılan arama başarılı olduktan sonra, kullanıcıdan SMS ile aldığı doğrulama kodunu yazmasını isteyin. Ardından kodu, signInWithPhoneNumber'ın istek karşılama işleyicisine (yani then bloğuna) iletilen ConfirmationResult nesnesinin confirm yöntemine ileterek kullanıcının oturumunu açın. Örnek:

Web modüler API

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web ad alanı API'si

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

confirm çağrısı başarılı olursa kullanıcının oturumu başarıyla açılır.

Ara AuthCredential nesnesini alma

Kullanıcının hesabı için bir AuthCredential nesnesi almanız gerekiyorsa confirm çağrısı yapmak yerine, onay sonucundaki doğrulama kodunu ve doğrulama kodunu PhoneAuthProvider.credential şirketine iletin:

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

Ardından, aşağıdaki kimlik bilgisini kullanarak kullanıcının oturum açmasını sağlayabilirsiniz:

firebase.auth().signInWithCredential(credential);

Hayali telefon numaralarıyla test etme

Firebase konsolu üzerinden geliştirme için kurgusal telefon numaraları ayarlayabilirsiniz. Hayali telefon numaralarıyla test yapmak şu avantajları sağlar:

  • Kullanım kotanızı tüketmeden telefon numarası kimlik doğrulamasını test edin.
  • Gerçek bir SMS mesajı göndermeden telefon numarası kimlik doğrulamasını test edin.
  • Kısıtlamadan, aynı telefon numarasıyla art arda testler yapın. Bu şekilde, incelemeci test için aynı telefon numarasını kullandığında uygulama mağazası inceleme sürecinde reddedilme riskini en aza indirir.
  • iOS simülatöründe veya Google Play Hizmetleri olmadan bir Android emülatöründe geliştirme yapabilmek gibi ek çaba sarf etmeden geliştirme ortamlarında kolayca test edebilirsiniz.
  • Entegrasyon testlerini, normalde üretim ortamında gerçek telefon numaralarına uygulanan güvenlik kontrolleri tarafından engellenmeden yazın.

Hayali telefon numaraları aşağıdaki şartları karşılamalıdır:

  1. Gerçekten hayali olan ve daha önce var olmayan telefon numaraları kullandığınızdan emin olun. Firebase Authentication, gerçek kullanıcılar tarafından kullanılan mevcut telefon numaralarını test numarası olarak ayarlamanıza izin vermez. Seçeneklerden biri, ABD test telefon numaraları olarak 555 önekli numarayı kullanmaktır. Örneğin: +1 650-555-3434
  2. Telefon numaralarının uzunluk ve diğer kısıtlamalar açısından doğru şekilde biçimlendirilmesi gerekir. Yine de gerçek bir kullanıcının telefon numarasıyla aynı doğrulamadan geçerler.
  3. Geliştirme için en fazla 10 telefon numarası ekleyebilirsiniz.
  4. Tahmin edilmesi zor test telefon numaraları/kodları kullanın ve bunları sık sık değiştirin.

Hayali telefon numaraları ve doğrulama kodları oluşturma

  1. Firebase konsolunda Kimlik Doğrulama bölümünü açın.
  2. Henüz yapmadıysanız Oturum açma yöntemi sekmesinde Telefon sağlayıcısını etkinleştirin.
  3. Test için telefon numaraları akordeon menüsünü açın.
  4. Test etmek istediğiniz telefon numarasını belirtin. Örneğin: +1 650-555-3434.
  5. Bu numara için 6 haneli doğrulama kodunu girin. Örneğin: 654321.
  6. Numarayı ekleyin. Gerekirse fareyle ilgili satırın üzerine gelip çöp kutusu simgesini tıklayarak telefon numarasını ve kodunu silebilirsiniz.

Manuel test

Uygulamanızda hayali bir telefon numarasını doğrudan kullanmaya başlayabilirsiniz. Bu sayede kota sorunları veya kısıtlamayla karşılaşmadan geliştirme aşamalarında manuel testler gerçekleştirebilirsiniz. Google Play Hizmetleri yüklü olmadan doğrudan bir iOS simülatörü veya Android emülatörü üzerinden de test yapabilirsiniz.

Hayali telefon numarasını sağlayıp doğrulama kodunu gönderdiğinizde gerçek bir SMS gönderilmez. Bunun yerine, oturum açma işlemini tamamlamak için önceden yapılandırılmış doğrulama kodunu sağlamanız gerekir.

Oturum açma işlemi tamamlandığında, bu telefon numarasıyla bir Firebase kullanıcısı oluşturulur. Kullanıcı, gerçek bir telefon numarası kullanıcısıyla aynı davranış ve özelliklere sahiptir ve Realtime Database/Cloud Firestore ile diğer hizmetlere aynı şekilde erişebilir. Bu işlem sırasında basılan kimlik jetonu, gerçek bir telefon numarası kullanıcısıyla aynı imzaya sahiptir.

Diğer bir seçenek de erişimi daha fazla kısıtlamak istiyorsanız bu kullanıcıları sahte kullanıcı olarak ayırt etmek için özel hak talepleri aracılığıyla bir test rolü belirlemektir.

Entegrasyon testi

Firebase Authentication, manuel teste ek olarak telefon kimlik doğrulama testi için entegrasyon testleri yazmaya yardımcı olacak API'ler de sağlar. Bu API'ler, iOS'te web ve sessiz push bildirimlerindeki reCAPTCHA şartını devre dışı bırakarak uygulama doğrulamayı devre dışı bırakır. Böylece bu akışlarda otomasyon testleri yapılabilir ve uygulanması kolaylaşır. Ayrıca, Android'de anında doğrulama akışlarını test etme imkanı sağlarlar.

Web'de, firebase.auth.RecaptchaVerifier öğesini oluşturmadan önce appVerificationDisabledForTesting öğesini true olarak ayarlayın. Bu işlem reCAPTCHA'yı otomatik olarak çözerek telefon numarasını manuel olarak çözmeden iletmenize olanak tanır. reCAPTCHA devre dışı bırakılmış olsa bile hayali olmayan bir telefon numarası kullanıldığında oturum açma işleminin tamamlanamayacağını unutmayın. Bu API ile yalnızca hayali telefon numaraları kullanılabilir.

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

Uygulama doğrulama devre dışı bırakıldığında, görünür ve görünmez reCAPTCHA uygulaması doğrulayıcıları farklı şekilde davranır:

  • Görünür reCAPTCHA: Görünür reCAPTCHA appVerifier.render() üzerinden oluşturulduğunda, ikinci bir gecikmenin ardından otomatik olarak kendi kendine çözümlenir. Bu, kullanıcının oluşturma işlemini tamamladıktan hemen sonra reCAPTCHA'yı tıklamasıdır. reCAPTCHA yanıtının bir süre sonra süresi dolar ve ardından tekrar otomatik olarak çözümlenir.
  • Görünmez reCAPTCHA: Görünmez reCAPTCHA, oluşturma sırasında otomatik olarak çözümlenmez. Bunun yerine, appVerifier.verify()çağrısında veya bir saniyeden kısa bir gecikmeden sonra reCAPTCHA'nın düğme bağlantısı tıklandığında bunu yapar. Benzer şekilde, yanıtın süresi bir süre sonra sona erer ve yalnızca appVerifier.verify() çağrısından sonra veya reCAPTCHA'nın düğme bağlantısı tekrar tıklandığında otomatik olarak çözümlenir.

Sahte reCAPTCHA çözüldüğünde, karşılık gelen geri çağırma işlevi beklendiği gibi sahte yanıtla tetiklenir. Sona erme süresi geri çağırması da belirtilirse süre dolduğunda tetiklenir.

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ı bilgisi) bağlanır. Bu yeni hesap Firebase projenizin bir parçası olarak depolanır ve kullanıcının nasıl oturum açtığından bağımsız olarak projenizdeki her uygulamada kullanıcıyı tanımlamak için kullanılabilir.

  • Uygulamalarınızda, kullanıcınızın kimlik doğrulama durumunu öğrenmek için önerilen yol, Auth nesnesinde bir gözlemci ayarlamaktır. Daha sonra, kullanıcının temel profil bilgilerini User nesnesinden alabilirsiniz. Kullanıcıları Yönetme sayfasına göz atın.

  • Firebase Realtime Database ve Cloud Storage Güvenlik Kurallarınızda, oturum açan 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, birden fazla kimlik doğrulama sağlayıcı kullanarak uygulamanızda oturum açmasına izin verebilirsiniz.

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

Web modüler API

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

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

Web ad alanı API'si

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