Xác thực bằng tính năng đăng nhập Facebook với JavaScript

Bạn có thể cho phép người dùng xác thực với Firebase bằng tài khoản Facebook của họ bằng cách tích hợp Đăng nhập Facebook vào ứng dụng của bạn. Bạn có thể tích hợp tính năng Đăng nhập Facebook bằng cách sử dụng Firebase SDK để thực hiện quy trình đăng nhập hoặc bằng cách thực hiện quy trình Đăng nhập Facebook theo cách thủ công và chuyển mã truy cập kết quả đến Firebase.

Trước khi bắt đầu

  1. Thêm Firebase vào dự án JavaScript của bạn.
  2. Trên Facebook for Developers trang web, hãy lấy Mã ứng dụngKhoá bí mật ứng dụng cho ứng dụng của bạn.
  3. Bật đăng nhập Facebook:
    1. Trong bảng điều khiển Firebase, hãy mở phần Xác thực.
    2. Trên thẻ Sign in method (Phương thức đăng nhập), hãy bật tính năng đăng nhập Facebook và chỉ định ID ứng dụngBí mật ứng dụng bạn đã nhận được từ Facebook.
    3. Sau đó, hãy đảm bảo URI chuyển hướng OAuth (ví dụ: my-app-12345.firebaseapp.com/__/auth/handler) được liệt kê là một trong các URI chuyển hướng OAuth trong trang cài đặt của ứng dụng Facebook trên trang web Facebook for Developers trong Cài đặt sản phẩm > Cấu hình đăng nhập Facebook.

Xử lý quy trình đăng nhập bằng Firebase SDK

Nếu bạn đang tạo một ứng dụng web thì cách dễ nhất để xác thực người dùng với Firebase thông qua tài khoản Facebook của họ là để xử lý quy trình đăng nhập bằng Firebase JavaScript SDK. (Nếu bạn muốn xác thực người dùng trong Node.js hoặc môi trường khác không phải trình duyệt, bạn phải xử lý luồng đăng nhập theo cách thủ công).

Để xử lý quy trình đăng nhập bằng SDK JavaScript của Firebase, hãy làm theo các bước sau các bước:

  1. Tạo một thực thể của đối tượng nhà cung cấp Facebook:
    WebWeb
    import { FacebookAuthProvider } from "firebase/auth";

    const provider = new FacebookAuthProvider();
    var provider = new firebase.auth.FacebookAuthProvider();
  2. Không bắt buộc: Chỉ định các phạm vi OAuth 2.0 khác mà bạn muốn yêu cầu từ nhà cung cấp dịch vụ xác thực. Để thêm phạm vi, hãy gọi addScope. Ví dụ:
    WebWeb
    provider.addScope('user_birthday');
    provider.addScope('user_birthday');
    Xem nhà cung cấp dịch vụ xác thực .
  3. Không bắt buộc: Để bản địa hoá quy trình OAuth của nhà cung cấp theo ưu tiên của người dùng ngôn ngữ mà không chuyển rõ ràng các tham số OAuth tuỳ chỉnh có liên quan, hãy cập nhật ngôn ngữ trên thực thể Xác thực trước khi bắt đầu quy trình OAuth. Ví dụ:
    WebWeb
    import { getAuth } from "firebase/auth";

    const auth = getAuth();
    auth
    .languageCode = 'it';
    // To apply the default browser preference instead of explicitly setting it.
    // auth.useDeviceLanguage();
    firebase.auth().languageCode = 'it';
    // To apply the default browser preference instead of explicitly setting it.
    // firebase.auth().useDeviceLanguage();
  4. Không bắt buộc: Chỉ định các thông số bổ sung của trình cung cấp OAuth tuỳ chỉnh mà bạn muốn gửi cùng với yêu cầu OAuth. Để thêm thông số tùy chỉnh, hãy gọi setCustomParameters trên trình cung cấp đã khởi tạo có một đối tượng chứa khoá như được chỉ định trong tài liệu về trình cung cấp OAuth và giá trị tương ứng. Ví dụ:
    WebWeb
    provider.setCustomParameters({
     
    'display': 'popup'
    });
    provider.setCustomParameters({
     
    'display': 'popup'
    });
    Các tham số OAuth bắt buộc đặt trước không được phép và sẽ bị bỏ qua. Hãy xem tài liệu tham khảo về nhà cung cấp dịch vụ xác thực để biết thêm chi tiết.
  5. Xác thực bằng Firebase sử dụng đối tượng nhà cung cấp Facebook. Bạn có thể nhắc người dùng đăng nhập bằng tài khoản Facebook của họ bằng cách mở cửa sổ bật lên hoặc bằng cách chuyển hướng đến trang đăng nhập. Phương thức chuyển hướng là được ưu tiên trên thiết bị di động.
    • Để đăng nhập bằng cửa sổ bật lên, hãy gọi signInWithPopup:
      WebWeb
      import { getAuth, signInWithPopup, FacebookAuthProvider } from "firebase/auth";

      const auth = getAuth();
      signInWithPopup
      (auth, provider)
       
      .then((result) => {
         
      // The signed-in user info.
         
      const user = result.user;

         
      // This gives you a Facebook Access Token. You can use it to access the Facebook API.
         
      const credential = FacebookAuthProvider.credentialFromResult(result);
         
      const accessToken = credential.accessToken;

         
      // 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 AuthCredential type that was used.
         
      const credential = FacebookAuthProvider.credentialFromError(error);

         
      // ...
       
      });
      firebase
       
      .auth()
       
      .signInWithPopup(provider)
       
      .then((result) => {
         
      /** @type {firebase.auth.OAuthCredential} */
         
      var credential = result.credential;

         
      // The signed-in user info.
         
      var user = result.user;
         
      // IdP data available in result.additionalUserInfo.profile.
           
      // ...

         
      // This gives you a Facebook Access Token. You can use it to access the Facebook API.
         
      var accessToken = credential.accessToken;

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

         
      // ...
       
      });
      Ngoài ra, xin lưu ý rằng bạn có thể truy xuất mã thông báo OAuth của nhà cung cấp Facebook. Mã này có thể dùng để tìm nạp thêm dữ liệu bằng API Facebook.

      Đây cũng là nơi bạn có thể phát hiện và xử lý các lỗi. Để biết danh sách mã lỗi, hãy xem Tài liệu tham khảo xác thực.

    • Để đăng nhập bằng cách chuyển hướng đến trang đăng nhập, hãy gọi signInWithRedirect: Làm theo các phương pháp hay nhất khi sử dụng tính năng "signInWith chuyển hướng".
      WebWeb
      import { getAuth, signInWithRedirect } from "firebase/auth";

      const auth = getAuth();
      signInWithRedirect
      (auth, provider);
      firebase.auth().signInWithRedirect(provider);
      Sau đó, bạn cũng có thể truy xuất mã thông báo OAuth của nhà cung cấp Facebook bằng cách gọi getRedirectResult khi trang của bạn tải:
      WebWeb
      import { getAuth, getRedirectResult, FacebookAuthProvider } from "firebase/auth";

      const auth = getAuth();
      getRedirectResult
      (auth)
       
      .then((result) => {
         
      // This gives you a Facebook Access Token. You can use it to access the Facebook API.
         
      const credential = FacebookAuthProvider.credentialFromResult(result);
         
      const token = credential.accessToken;

         
      const user = result.user;
         
      // 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;
         
      // AuthCredential type that was used.
         
      const credential = FacebookAuthProvider.credentialFromError(error);
         
      // ...
       
      });
      firebase.auth()
       
      .getRedirectResult()
       
      .then((result) => {
         
      if (result.credential) {
           
      /** @type {firebase.auth.OAuthCredential} */
           
      var credential = result.credential;

           
      // This gives you a Facebook Access Token. You can use it to access the Facebook API.
           
      var token = credential.accessToken;
           
      // ...
         
      }
         
      // The signed-in user info.
         
      var user = result.user;
         
      // 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;
         
      // ...
       
      });
      Đây cũng là nơi bạn có thể phát hiện và xử lý các lỗi. Để biết danh sách mã lỗi, hãy xem Tài liệu tham khảo xác thực.

Nếu bạn đã bật chế độ cài đặt Một tài khoản cho mỗi địa chỉ email trong bảng điều khiển của Firebase, khi người dùng cố gắng đăng nhập vào một nhà cung cấp (chẳng hạn như Facebook) bằng một email đã cho một nhà cung cấp khác của người dùng Firebase (chẳng hạn như Google), thì lỗi auth/account-exists-with-different-credential được gửi cùng với Đối tượng AuthCredential (mã truy cập Facebook). Để hoàn tất quá trình đăng nhập vào nhà cung cấp dự định, trước tiên người dùng phải đăng nhập vào nhà cung cấp hiện tại (Google) và sau đó liên kết với AuthCredential cũ (mã truy cập Facebook).

Nếu sử dụng signInWithPopup, bạn có thể xử lý auth/account-exists-with-different-credential lỗi với mã như sau ví dụ:

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

try {
 
// Step 1: User tries to sign in using Facebook.
  let result
= await signInWithPopup(getAuth(), new FacebookAuthProvider());
} catch (error) {
 
// Step 2: User's email already exists.
 
if (error.code === "auth/account-exists-with-different-credential") {
   
// The pending Facebook credential.
    let pendingCred
= error.credential;

   
// Step 3: Save the pending credential in temporary storage,

   
// Step 4: Let the user know that they already have an account
   
// but with a different provider, and let them choose another
   
// sign-in method.
 
}
}

// ...

try {
 
// Step 5: Sign the user in using their chosen method.
  let result
= await signInWithPopup(getAuth(), userSelectedProvider);

 
// Step 6: Link to the Facebook credential.
 
// TODO: implement `retrievePendingCred` for your app.
  let pendingCred
= retrievePendingCred();

 
if (pendingCred !== null) {
   
// As you have access to the pending credential, you can directly call the
   
// link method.
    let user
= await linkWithCredential(result.user, pendingCred);
 
}

 
// Step 7: Continue to app.
} catch (error) {
 
// ...
}

Chế độ chuyển hướng

Lỗi này được xử lý theo cách tương tự trong chế độ chuyển hướng, chỉ khác là thông tin đăng nhập phải được lưu vào bộ nhớ đệm giữa các lần chuyển hướng trang (ví dụ: sử dụng bộ nhớ phiên).

Bạn cũng có thể xác thực với Firebase bằng tài khoản Facebook bằng cách xử lý quy trình đăng nhập bằng SDK JavaScript đăng nhập Facebook:

  1. Tích hợp Đăng nhập Facebook vào ứng dụng của bạn bằng cách làm theo tài liệu dành cho nhà phát triển. Đảm bảo định cấu hình Đăng nhập Facebook bằng ID ứng dụng Facebook của bạn:
    <script src="//connect.facebook.net/en_US/sdk.js"></script>
    <script>
      FB
    .init({
       
    /**********************************************************************
         * TODO(Developer): Change the value below with your Facebook app ID. *
         **********************************************************************/

        appId
    : '<YOUR_FACEBOOK_APP_ID>',
        status
    : true,
        xfbml
    : true,
        version
    : 'v2.6',
     
    });
    </script>
  2. Chúng ta cũng thiết lập trình nghe trên trạng thái xác thực Facebook:
    FB.Event.subscribe('auth.authResponseChange', checkLoginState);
  3. Sau khi bạn tích hợp tính năng Đăng nhập Facebook, hãy thêm nút Đăng nhập Facebook vào các trang web của bạn:
    <fb:login-button
     
    data-auto-logout-link="true"
     
    scope="public_profile,email"
     
    size="large"
    ></fb:login-button>
  4. Trong lệnh gọi lại trạng thái xác thực Facebook, hãy trao đổi mã thông báo xác thực từ phản hồi xác thực của Facebook để có thông tin xác thực Firebase và đăng nhập Firebase:
    WebWeb
    import { getAuth, onAuthStateChanged, signInWithCredential, signOut, FacebookAuthProvider } from "firebase/auth";
    const auth = getAuth();

    function checkLoginState(response) {
     
    if (response.authResponse) {
       
    // User is signed-in Facebook.
       
    const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
          unsubscribe
    ();
         
    // Check if we are already signed-in Firebase with the correct user.
         
    if (!isUserEqual(response.authResponse, firebaseUser)) {
           
    // Build Firebase credential with the Facebook auth token.
           
    const credential = FacebookAuthProvider.credential(
                response
    .authResponse.accessToken);

           
    // Sign in with the credential from the Facebook user.
            signInWithCredential
    (auth, credential)
             
    .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 AuthCredential type that was used.
               
    const credential = FacebookAuthProvider.credentialFromError(error);
               
    // ...
             
    });
         
    } else {
           
    // User is already signed-in Firebase with the correct user.
         
    }
       
    });
     
    } else {
       
    // User is signed-out of Facebook.
        signOut
    (auth);
     
    }
    }
    function checkLoginState(response) {
     
    if (response.authResponse) {
       
    // User is signed-in Facebook.
       
    var unsubscribe = firebase.auth().onAuthStateChanged((firebaseUser) => {
          unsubscribe
    ();
         
    // Check if we are already signed-in Firebase with the correct user.
         
    if (!isUserEqual(response.authResponse, firebaseUser)) {
           
    // Build Firebase credential with the Facebook auth token.
           
    var credential = firebase.auth.FacebookAuthProvider.credential(
                response
    .authResponse.accessToken);

           
    // Sign in with the credential from the Facebook user.
            firebase
    .auth().signInWithCredential(credential)
             
    .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;
               
    // ...
             
    });
         
    } else {
           
    // User is already signed-in Firebase with the correct user.
         
    }
       
    });
     
    } else {
       
    // User is signed-out of Facebook.
        firebase
    .auth().signOut();
     
    }
    }
    Đây cũng là nơi bạn có thể phát hiện và xử lý các lỗi. Để biết danh sách mã lỗi, hãy xem Tài liệu tham khảo xác thực.
  5. Ngoài ra, bạn nên kiểm tra để đảm bảo rằng người dùng Facebook chưa đăng nhập vào Firebase để tránh việc xác thực lại không cần thiết:
    WebWeb
    import { FacebookAuthProvider } from "firebase/auth";

    function isUserEqual(facebookAuthResponse, firebaseUser) {
     
    if (firebaseUser) {
       
    const providerData = firebaseUser.providerData;
       
    for (let i = 0; i < providerData.length; i++) {
         
    if (providerData[i].providerId === FacebookAuthProvider.PROVIDER_ID &&
              providerData
    [i].uid === facebookAuthResponse.userID) {
           
    // We don't need to re-auth the Firebase connection.
           
    return true;
         
    }
       
    }
     
    }
     
    return false;
    }
    function isUserEqual(facebookAuthResponse, firebaseUser) {
     
    if (firebaseUser) {
       
    var providerData = firebaseUser.providerData;
       
    for (var i = 0; i < providerData.length; i++) {
         
    if (providerData[i].providerId === firebase.auth.FacebookAuthProvider.PROVIDER_ID &&
              providerData
    [i].uid === facebookAuthResponse.userID) {
           
    // We don't need to re-auth the Firebase connection.
           
    return true;
         
    }
       
    }
     
    }
     
    return false;
    }

Cách xác thực bằng Firebase trong ứng dụng Node.js:

  1. Đăng nhập người dùng bằng tài khoản Facebook của họ và tải Facebook của người dùng mã truy cập. Ví dụ: đăng nhập người dùng trong một trình duyệt như mô tả trong dịch vụ Xử lý hoạt động đăng nhập theo cách thủ công, nhưng hãy gửi mã truy cập đến Node.js của bạn thay vì sử dụng trong ứng dụng khách.
  2. Sau khi bạn nhận được mã truy cập Facebook của người dùng, hãy sử dụng mã đó để tạo đối tượng thông tin xác thực rồi đăng nhập người dùng bằng thông tin đăng nhập đó:
    WebWeb
    import { getAuth, signInWithCredential, FacebookAuthProvider } from "firebase/auth";

    // Sign in with the credential from the Facebook user.
    const auth = getAuth();
    signInWithCredential
    (auth, credential)
     
    .then((result) => {
       
    // Signed in
       
    const credential = FacebookAuthProvider.credentialFromResult(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 AuthCredential type that was used.
       
    const credential = FacebookAuthProvider.credentialFromError(error);
       
    // ...
     
    });
    // Sign in with the credential from the Facebook user.
    firebase
    .auth().signInWithCredential(credential)
     
    .then((result) => {
       
    // Signed in      
       
    var credential = result.credential;
       
    // ...
     
    })
     
    .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;
       
    // ...
     
    });

Xác thực bằng Firebase trong một tiện ích của Chrome

Nếu bạn đang xây dựng ứng dụng tiện ích của Chrome, hãy xem Hướng dẫn về tài liệu ngoài màn hình

Khi tạo dự án, Firebase sẽ cung cấp một miền con duy nhất cho dự án của bạn: https://my-app-12345.firebaseapp.com.

Cơ chế này cũng sẽ được dùng làm cơ chế chuyển hướng cho việc đăng nhập bằng OAuth. Miền đó cần phải được phép đối với tất cả các nhà cung cấp OAuth được hỗ trợ. Tuy nhiên, điều này có nghĩa là người dùng có thể thấy rằng trong khi đăng nhập vào Facebook trước khi chuyển hướng trở lại ứng dụng: Tiếp tục truy cập: https://my-app-12345.firebaseapp.com.

Để tránh hiển thị miền con, bạn có thể thiết lập miền tuỳ chỉnh bằng Firebase Hosting:

  1. Làm theo các bước từ 1 đến 3 trong Thiết lập miền của bạn cho Hosting. Khi bạn xác minh quyền sở hữu miền của bạn, Hosting cung cấp chứng chỉ SSL cho miền tuỳ chỉnh của bạn.
  2. Thêm miền tuỳ chỉnh của bạn vào danh sách các miền được uỷ quyền trong Bảng điều khiển Firebase: auth.custom.domain.com.
  3. Trong bảng điều khiển dành cho nhà phát triển Facebook hoặc trang thiết lập OAuth, hãy thêm URL của trang chuyển hướng vào danh sách trắng, bạn có thể truy cập vào tệp này trên miền tuỳ chỉnh của mình: https://auth.custom.domain.com/__/auth/handler.
  4. Khi bạn khởi chạy thư viện JavaScript, hãy chỉ định miền tuỳ chỉnh của bạn bằng Trường authDomain:
    var config = {
      apiKey
    : '...',
     
    // Changed from 'my-app-12345.firebaseapp.com'.
      authDomain
    : 'auth.custom.domain.com',
      databaseURL
    : 'https://my-app-12345.firebaseio.com',
      projectId
    : 'my-app-12345',
      storageBucket
    : 'my-app-12345.appspot.com',
      messagingSenderId
    : '1234567890'
    };
    firebase
    .initializeApp(config);

Các bước tiếp theo

Sau khi người dùng đăng nhập lần đầu tiên, một tài khoản người dùng mới sẽ được tạo và được liên kết với thông tin đăng nhập—tức là tên người dùng và mật khẩu, số điện thoại số hoặc thông tin của nhà cung cấp dịch vụ xác thực – người dùng đã đăng nhập. Thông tin mới này được lưu trữ như một phần của dự án Firebase và có thể được dùng để xác định một người dùng trên mọi ứng dụng trong dự án của bạn, bất kể người dùng đăng nhập bằng cách nào.

  • Trong ứng dụng của mình, bạn nên sử dụng cách để biết trạng thái xác thực của người dùng đặt trình quan sát trên đối tượng Auth. Sau đó, bạn có thể lấy thông tin thông tin hồ sơ cơ bản của đối tượng User. Xem Quản lý người dùng.

  • Trong Firebase Realtime DatabaseCloud Storage của bạn Quy tắc bảo mật, bạn có thể lấy mã nhận dạng người dùng duy nhất của người dùng đã đăng nhập từ biến auth, để kiểm soát loại dữ liệu mà người dùng có thể truy cập.

Bạn có thể cho phép người dùng đăng nhập vào ứng dụng của mình bằng nhiều phương thức xác thực bằng cách liên kết thông tin đăng nhập của nhà cung cấp dịch vụ xác thực với tài khoản người dùng hiện có.

Để đăng xuất một người dùng, hãy gọi signOut:

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

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