Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

通過JavaScript使用Apple進行身份驗證

您可以使用Firebase SDK來執行端到端OAuth 2.0登錄流程,從而使用戶使用其Apple ID向Firebase進行身份驗證。

在你開始之前

要使用Apple登錄用戶,請首先在Apple的開發人員站點上配置“使用Apple登錄”,然後將Apple啟用為Firebase項目的登錄提供程序。

加入蘋果開發者計劃

使用Apple登錄只能由Apple Developer Program的成員配置。

使用Apple配置登錄

Apple Developer網站上,執行以下操作:

  1. 使用“為網絡配置Apple登錄”的第一部分所述,將您的網站與您的應用程序關聯。出現提示時,將以下URL註冊為返回URL:

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

    您可以在Firebase控制台設置頁面上獲取Firebase項目ID。

    完成後,記下新的服務ID,這將在下一部分中使用。

  2. 使用Apple私鑰創建登錄。在下一部分中,您將需要新的私鑰和密鑰ID。
  3. 如果您使用Firebase Authentication的任何向用戶發送電子郵件的功能,包括電子郵件鏈接登錄,電子郵件地址驗證,帳戶更改吊銷等,請配置Apple私人電子郵件中繼服務並註冊noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (或您的自定義電子郵件模板域),以便Apple可以將Firebase Authentication發送的電子郵件中繼到匿名的Apple電子郵件地址。

使Apple成為登錄提供商

  1. 將Firebase添加到您的項目中
  2. Firebase控制台中,打開“身份驗證”部分。在“登錄方法”選項卡上,啟用Apple提供程序。指定您在上一節中創建的服務ID。另外,在OAuth代碼流配置部分中,指定您的Apple Team ID以及您在上一部分中創建的私鑰和密鑰ID。

符合Apple匿名數據要求

使用Apple登錄可以為用戶提供在登錄時匿名化其數據(包括其電子郵件地址)的選項。選擇此選項的用戶的電子郵件地址的域為privaterelay.appleid.com 。當您在應用中使用“通過Apple登錄”時,您必須遵守Apple關於這些匿名Apple ID的所有適用開發人員政策或條款。

這包括在將任何直接識別的個人信息與匿名的Apple ID相關聯之前,獲得所有必需的用戶同意。使用Firebase身份驗證時,這可能包括以下操作:

  • 將電子郵件地址鏈接到匿名的Apple ID,反之亦然。
  • 將電話號碼鏈接到匿名的Apple ID,反之亦然
  • 將非匿名社交憑據(Facebook,Google等)鏈接到匿名Apple ID,反之亦然。

上面的列表並不詳盡。請參閱開發人員帳戶的“成員資格”部分中的“ Apple開發人員計劃許可協議”,以確保您的應用程序滿足Apple的要求。

使用Firebase SDK處理登錄流程

如果要構建Web應用程序,則使用用戶的Apple帳戶向Firebase進行身份驗證的最簡單方法是使用Firebase JavaScript SDK處理整個登錄流程。

要使用Firebase JavaScript SDK處理登錄流程,請按照以下步驟操作:

  1. 使用相應的提供程序ID apple.com創建OAuthProvider的實例。

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. 可選:指定要從身份驗證提供程序請求的默認範圍以外的其他OAuth 2.0範圍。

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

    默認情況下,啟用每個電子郵件地址一個帳戶後,Firebase會請求電子郵件和名稱範圍。如果將此設置更改為“每個電子郵件地址多個帳戶” ,除非您指定它們,否則Firebase不會向Apple請求任何範圍。

  3. 可選:如果要以英語以外的其他語言顯示Apple的登錄屏幕,請設置locale參數。有關受支持的語言環境,請參閱“ 使用Apple登錄”

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. 使用OAuth提供程序對象向Firebase進行身份驗證。您可以通過打開彈出窗口或重定向到登錄頁面來提示用戶使用其Apple帳戶登錄。在移動設備上首選重定向方法。

    • 要使用彈出窗口登錄,請調用signInWithPopup()

      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;
      
          // ...
        })
        .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;
      
          // ...
        });
    • 要通過重定向到登錄頁面來登錄,請調用signInWithRedirect()

      firebase.auth().signInWithRedirect(provider);

      用戶完成登錄並返回頁面後,您可以通過調用getRedirectResult()獲得登錄結果:

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

      這也是您可以捕獲和處理錯誤的地方。有關錯誤代碼的列表,請參見API參考

    與Firebase Auth支持的其他提供程序不同,Apple不提供照片URL。

    另外,當用戶選擇不與應用程序共享電子郵件時,Apple會為該用戶提供一個唯一的電子郵件地址(格式為xyz@privaterelay.appleid.com ),並與您的應用程序共享。如果您配置了私人電子郵件中繼服務,Apple會將發送到匿名地址的電子郵件轉發到用戶的真實電子郵件地址。

    Apple僅在用戶首次登錄時與應用共享用戶信息,例如顯示名稱。通常,Firebase會存儲用戶首次登錄Apple時的顯示名稱,您可以通過firebase.auth().currentUser.displayName獲得該名稱firebase.auth().currentUser.displayName 。但是,如果您以前使用Apple在不使用Firebase的情況下將用戶登錄到應用程序,則Apple不會為Firebase提供用戶的顯示名稱。

重新認證和帳戶關聯

可以將相同的模式與reauthenticateWithPopup()reauthenticateWithRedirect()使用,可以將其用於檢索需要最近登錄的敏感操作的新憑據:

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;

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

    // ...
  });

並且,您可以使用linkWithPopup()linkWithRedirect()將不同的身份提供者鏈接到現有帳戶。

請注意,在將用戶的Apple帳戶鏈接到其他數據之前,Apple要求您獲得用戶的明確同意。

例如,要將Facebook帳戶鏈接到當前的Firebase帳戶,請使用從用戶登錄Facebook獲得的訪問令牌:

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擴展程序中使用Firebase進行身份驗證

如果要構建Chrome擴展程序,則必須添加Chrome擴展程序ID:

  1. Firebase控制台中打開您的項目。
  2. 在“身份驗證”部分中,打開“登錄方法”頁面。
  3. 將以下類似的URI添加到“授權域”列表中:
    chrome-extension://CHROME_EXTENSION_ID

Chrome擴展程序僅可使用彈出操作( signInWithPopuplinkWithPopup ),因為Chrome擴展程序無法使用HTTP重定向。您應該從後台腳本而不是瀏覽器操作彈出窗口調用這些方法,因為身份驗證彈出窗口將取消瀏覽器操作彈出窗口。

確保在Chrome擴展程序的清單文件中,將https://apis.google.com URL添加到content_security_policy允許列表。

請注意,您仍然必須使用Apple驗證自定義域,類似於默認的firebaseapp.com域:

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

進階:在Node.js中使用Firebase進行驗證

要在Node.js應用程序中使用Firebase進行身份驗證,請執行以下操作:

  1. 使用其Apple帳戶登錄用戶並獲取用戶的Apple ID令牌。您可以通過多種方式完成此操作。例如,如果您的Node.js應用程序具有瀏覽器前端:

    1. 在您的後端,生成一個隨機字符串(“ nonce”)併計算其SHA256哈希。隨機數是一次性使用價值,用於驗證後端與Apple的身份驗證服務器之間的一次往返。

      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.substr(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');
    2. 在登錄頁面上,在“使用Apple登錄”配置中指定哈希隨機數:

      <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. 從POST身份驗證響應服務器端獲取Apple ID令牌:

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

    另請參閱配置網頁以使用Apple登錄

  2. 獲取用戶的Apple ID令牌後,可使用它來構建憑據對象,然後使用憑據登錄用戶:

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

下一步

用戶首次登錄後,將創建一個新的用戶帳戶並將其鏈接到該用戶登錄的憑據(即用戶名和密碼,電話號碼或身份驗證提供者信息)。此新帳戶存儲為Firebase項目的一部分,可用於在項目中的每個應用程序中識別用戶,而無論用戶如何登錄。

  • 在您的應用程序中,建議的了解用戶身份驗證狀態的方法是在Auth對像上設置觀察者。然後,您可以從User對象獲取用戶的基本配置文件信息。請參閱管理用戶

  • 在Firebase實時數據庫和雲存儲安全規則中,您可以從auth變量中獲取登錄用戶的唯一用戶ID,然後使用它來控制用戶可以訪問哪些數據。

通過將身份驗證提供程序憑據鏈接到現有用戶帳戶,可以允許用戶使用多個身份驗證提供程序登錄您的應用程序

要註銷用戶,請致電signOut

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