JavaScript ile Apple Kullanarak Kimlik Doğrulama

Uçtan uca OAuth 2.0 oturum açma akışını gerçekleştirmek için Firebase SDK'sını kullanarak kullanıcılarınızın Apple kimliklerini kullanarak Firebase ile kimlik doğrulamasına izin verebilirsiniz.

Başlamadan önce

Apple'ı kullanarak kullanıcıların oturumunu açmak için önce Apple'ın geliştirici sitesinde Apple ile Oturum Açma özelliğini yapılandırın, ardından Apple'ı Firebase projeniz için oturum açma sağlayıcısı olarak etkinleştirin.

Apple Developer Program'a katılma

Apple ile oturum açma özelliği yalnızca Apple Developer Programı'nın üyeleri tarafından yapılandırılabilir.

Apple ile oturum açma özelliğini yapılandırma

Apple Developer sitesinde aşağıdakileri yapın:

  1. Web için Apple ile oturum açma özelliğini yapılandırma başlıklı makalenin ilk bölümünde açıklandığı şekilde web sitenizi uygulamanızla ilişkilendirin. İstendiğinde aşağıdaki URL'yi Dönüş URL'si olarak kaydedin:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Firebase proje kimliğinizi Firebase konsolu ayarlar sayfasından edinebilirsiniz.

    İşlemi tamamladığınızda yeni hizmet kimliğinizi not edin. Bu kimliğe bir sonraki bölümde ihtiyacınız olacak.

  2. Apple ile oturum aç özel anahtarı oluşturun. Bir sonraki bölümde yeni özel anahtarınızı ve anahtar kimliğinizi kullanmanız gerekir.
  3. E-posta bağlantısı ile oturum açma, e-posta adresi doğrulama, hesap değişikliği iptal etme ve diğerleri dahil olmak üzere Firebase Authentication'ın kullanıcılara e-posta gönderen özelliklerinden herhangi birini kullanıyorsanız Apple özel e-posta geçiş hizmetini yapılandırın ve Apple'ın Firebase Authentication tarafından gönderilen e-postaları anonimleştirilmiş Apple e-posta adreslerine iletebilmesi için noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com (veya özelleştirilmiş e-posta şablonu alanınızı) kaydedin.

Apple'ı oturum açma sağlayıcısı olarak etkinleştirme

  1. Firebase'i projenize ekleyin.
  2. Firebase konsolunda Auth bölümünü açın. Oturum açma yöntemi sekmesinde Apple sağlayıcısını etkinleştirin. Önceki bölümde oluşturduğunuz hizmet kimliğini belirtin. Ayrıca, OAuth kod akışı yapılandırması bölümünde Apple ekip kimliğinizi, önceki bölümde oluşturduğunuz özel anahtarı ve anahtar kimliğini belirtin.

Apple'ın anonimleştirilmiş veri şartlarına uyma

Apple ile oturum açma özelliği, kullanıcılara oturum açarken e-posta adresleri de dahil olmak üzere verilerini anonimleştirme seçeneği sunar. Bu seçeneği belirleyen kullanıcıların e-posta adresleri privaterelay.appleid.com alan adıyla başlar. Uygulamanızda Apple ile oturum açma özelliğini kullandığınızda, bu anonimleştirilmiş Apple kimlikleriyle ilgili Apple'ın geçerli geliştirici politikalarına veya şartlarına uymanız gerekir.

Buna, doğrudan kimliği tanımlayan kişisel bilgileri anonimleştirilmiş bir Apple kimliğiyle ilişkilendirmeden önce gerekli kullanıcı rızasını almak da dahildir. Firebase Authentication kullanılırken bu işlemler aşağıdakileri içerebilir:

  • Bir e-posta adresini anonimleştirilmiş bir Apple Kimliği'ne veya anonimleştirilmiş bir Apple Kimliği'ni bir e-posta adresine bağlayabilirsiniz.
  • Telefon numarasını anonimleştirilmiş bir Apple Kimliği'ne veya anonimleştirilmiş Apple Kimliği'ni telefon numarasına bağlama
  • Anonim olmayan bir sosyal kimlik bilgisini (Facebook, Google vb.) anonimleştirilmiş bir Apple kimliğine veya tam tersini bağlama

Yukarıdaki listede olası her duruma yer verilmemiştir. Uygulamanızın Apple'ın şartlarını karşıladığından emin olmak için geliştirici hesabınızın Üyelik bölümündeki Apple Geliştirici Programı Lisans Sözleşmesi'ne bakın.

Oturum açma akışını Firebase SDK'sıyla yönetme

Web uygulaması geliştiriyorsanız kullanıcılarınızın Apple hesaplarını kullanarak Firebase ile kimliklerini doğrulamanın en kolay yolu, oturum açma akışının tamamını Firebase JavaScript SDK'sıyla yönetmek olacaktır.

Oturum açma akışını Firebase JavaScript SDK'sıyla işlemek için aşağıdaki adımları uygulayın:

  1. İlgili sağlayıcı kimliğini (apple.com) kullanarak bir OAuthProvider örneği oluşturun.

    Web

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('apple.com');

    Web

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. İsteğe bağlı: Kimlik doğrulama sağlayıcıdan istemek istediğiniz varsayılan kapsamların dışında ek OAuth 2.0 kapsamları belirtin.

    Web

    provider.addScope('email');
    provider.addScope('name');

    Web

    provider.addScope('email');
    provider.addScope('name');

    E-posta adresi başına bir hesap etkinleştirildiğinde Firebase varsayılan olarak e-posta ve ad kapsamlarını ister. Bu ayarı E-posta adresi başına birden fazla hesap olarak değiştirirseniz Firebase, siz belirtmediğiniz sürece Apple'dan kapsam istemiyor.

  3. İsteğe bağlı: Apple'ın oturum açma ekranını İngilizce dışında bir dilde görüntülemek istiyorsanız locale parametresini ayarlayın. Desteklenen yerel ayarlar için Apple ile oturum açma dokümanlarına göz atın.

    Web

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });

    Web

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. OAuth sağlayıcı nesnesini kullanarak Firebase ile kimlik doğrulama Kullanıcılarınızın Apple Hesaplarıyla oturum açmasını isteyebilirsiniz. Bunun için pop-up pencere açabilir veya oturum açma sayfasına yönlendirebilirsiniz. Yönlendirme yöntemi, mobil cihazlarda tercih edilir.

    • Pop-up pencereyle oturum açmak için signInWithPopup() numaralı telefonu arayın:

      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;
      
          // IdP data available using getAdditionalUserInfo(result)
          // ...
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

      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;
      
          // IdP data available using getAdditionalUserInfo(result)
        // ...
        })
        .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;
      
          // ...
        });
    • Oturum açma sayfasına yönlendirerek oturum açmak için signInWithRedirect()numarasını arayın:

    signInWithRedirect, linkWithRedirect veya reauthenticateWithRedirect'i kullanırken en iyi uygulamaları takip edin.

    Web

    import { getAuth, signInWithRedirect } from "firebase/auth";
    
    const auth = getAuth();
    signInWithRedirect(auth, provider);

    Web

    firebase.auth().signInWithRedirect(provider);

    Kullanıcı oturum açmayı tamamlayıp sayfaya döndükten sonra getRedirectResult() işlevini çağırarak oturum açma sonucunu alabilirsiniz:

    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.customData.email;
        // The credential that was used.
        const credential = OAuthProvider.credentialFromError(error);
    
        // ...
      });

    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;
    
          // IdP data available in result.additionalUserInfo.profile.
          // ...
        }
        // 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;
    
        // ...
      });

    Hataları yakalayıp buradan da yönetebilirsiniz. Hata kodlarının listesini API referansında bulabilirsiniz.

    Firebase Auth tarafından desteklenen diğer sağlayıcıların aksine Apple, fotoğraf URL'si sağlamaz.

    Ayrıca, kullanıcı e-posta adresini uygulamayla paylaşmayı tercih etmediğinde Apple, bu kullanıcı için benzersiz bir e-posta adresi (xyz@privaterelay.appleid.com biçiminde) oluşturur ve uygulamanızla paylaşır. Özel e-posta geçiş hizmetini yapılandırdıysanız Apple, anonimleştirilmiş adrese gönderilen e-postaları kullanıcının gerçek e-posta adresine yönlendirir.

    Apple, görünen ad gibi kullanıcı bilgilerini yalnızca kullanıcının ilk kez oturum açtığı uygulamalarla paylaşır. Firebase genellikle kullanıcının Apple ile ilk kez oturum açtığı sırada görünen adı depolar. Bu adı firebase.auth().currentUser.displayName ile alabilirsiniz. Ancak daha önce Firebase'i kullanmadan bir kullanıcının uygulamada oturum açması için Apple'ı kullandıysanız Apple, Firebase'e kullanıcının görünen adını sağlamaz.

Yeniden kimlik doğrulama ve hesap bağlama

Aynı kalıp, son oturum açmayı gerektiren hassas işlemler için yeni bir kimlik bilgisi almak üzere kullanabileceğiniz reauthenticateWithPopup() ve reauthenticateWithRedirect() ile kullanılabilir:

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.customData.email;
    // The credential that was used.
    const credential = OAuthProvider.credentialFromError(error);

    // ...
  });

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;

    // IdP data available in result.additionalUserInfo.profile.
      // ...
  })
  .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;

    // ...
  });

Ayrıca, farklı kimlik sağlayıcıları mevcut hesaplara bağlamak için linkWithPopup() ve linkWithRedirect() öğelerini kullanabilirsiniz.

Apple, Apple hesaplarını diğer verilere bağlamadan önce kullanıcılardan açık izin almanızı zorunlu kılar.

Örneğin, bir Facebook hesabını mevcut Firebase hesabına bağlamak için kullanıcının Facebook'ta oturum açmasından elde ettiğiniz erişim jetonunu kullanın:

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

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

Chrome uzantısında Firebase ile kimlik doğrulama

Chrome uzantısı uygulaması geliştiriyorsanız Ekran Dışı Dokümanlar kılavuzuna göz atın.

Özel alanı, varsayılan firebaseapp.com alanına benzer şekilde Apple ile doğrulamanız gerektiğini unutmayın:

http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt

Jeton iptal etme

Apple, hesap oluşturma özelliğini destekleyen uygulamaların, App Store İnceleme Yönergeleri'nde açıklandığı gibi kullanıcıların hesaplarını uygulama içinden silmelerine izin vermesini zorunlu kılar.

Bu koşulu karşılamak için aşağıdaki adımları uygulayın:

  1. Apple ile oturum açma özelliğini yapılandırma bölümünde açıklandığı gibi, Apple ile oturum açma sağlayıcı yapılandırmasının Hizmet Kimliği ve OAuth kod akışı yapılandırması bölümünü doldurduğunuzdan emin olun.

  2. Firebase, Apple ile oturum açma özelliği kullanılarak oluşturulan kullanıcı jetonlarını depolamadığından, jetonu iptal edip hesabı silmeden önce kullanıcıdan tekrar oturum açmasını istemeniz gerekir.

    Ardından, OAuthCredential'ten Apple OAuth erişim jetonunu alın ve Apple OAuth erişim jetonunu iptal etmek için revokeAccessToken(auth, token)'i çağırmak üzere kullanın.

    const provider = new OAuthProvider('apple.com');
    provider.addScope('email');
    provider.addScope('name');
    
    const auth = getAuth();
    signInWithPopup(auth, provider).then(result => {
      // Get the Apple OAuth access token.
      const credential = OAuthProvider.credentialFromResult(result);
      const accessToken = credential.accessToken;
    
      // Revoke the Apple OAuth access token.
      revokeAccessToken(auth, accessToken)
        .then(() => {
          // Token revoked.
    
          // Delete the user account.
          // ...
        })
        .catch(error => {
          // An error happened.
          // ...
        });
    });
    
  3. Son olarak, kullanıcı hesabını (ve ilişkili tüm verileri) silin.

İleri seviye: Node.js'de Firebase ile kimlik doğrulama

Node.js uygulamasında Firebase ile kimlik doğrulamak için:

  1. Kullanıcının Apple Hesabı ile oturum açın ve kullanıcının Apple kimliği jetonunu alın. Bunu birkaç şekilde yapabilirsiniz. Örneğin, Node.js uygulamanızda tarayıcı ön ucu varsa:

    1. Arka uçta rastgele bir dize ("tek seferlik") oluşturun ve SHA256 karmasını hesaplayın. Tek seferlik sayı, arka uç ile Apple'ın kimlik doğrulama sunucuları arasında tek bir gidiş dönüş işlemini doğrulamak için kullandığınız tek kullanımlık bir değerdir.

      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.slice(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');

      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.slice(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');
    2. Oturum açma sayfanızda, Apple ile oturum açma yapılandırmanızdaki karma oluşturma işlemi uygulanmış tek seferlik değeri belirtin:

      <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>
      
    3. Gönderilen kimlik doğrulama yanıtından Apple kimliği jetonunu sunucu tarafında alma:

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

    Web sayfanızı Apple ile oturum açma için yapılandırma başlıklı makaleyi de inceleyin.

  2. Kullanıcının Apple Kimliği jetonunu aldıktan sonra, kimlik bilgisi nesnesi oluşturmak için kullanın ve ardından kimlik bilgisiyle kullanıcının oturumunu açın:

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

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

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