Xác thực với Firebase bằng số điện thoại bằng JavaScript

Bạn có thể sử dụng Xác thực Firebase để đăng nhập người dùng bằng cách gửi tin nhắn SMS đến điện thoại của người dùng. Người dùng đăng nhập bằng mã một lần có trong tin nhắn SMS.

Cách dễ nhất để thêm đăng nhập bằng số điện thoại vào ứng dụng của bạn là sử dụng FirebaseUI , bao gồm tiện ích đăng nhập thả xuống triển khai các luồng đăng nhập cho đăng nhập bằng số điện thoại, cũng như đăng nhập dựa trên mật khẩu và đăng nhập có liên kết -TRONG. Tài liệu này mô tả cách triển khai quy trình đăng nhập bằng số điện thoại bằng SDK Firebase.

Trước khi bắt đầu

Nếu bạn chưa có, hãy sao chép đoạn mã khởi tạo từ bảng điều khiển Firebase vào dự án của bạn như được mô tả trong Thêm Firebase vào dự án JavaScript của bạn .

mối quan tâm an ninh

Xác thực chỉ sử dụng một số điện thoại, mặc dù thuận tiện, nhưng lại kém an toàn hơn so với các phương pháp khả dụng khác, bởi vì việc sở hữu một số điện thoại có thể dễ dàng chuyển giao giữa những người dùng. Ngoài ra, trên các thiết bị có nhiều hồ sơ người dùng, bất kỳ người dùng nào có thể nhận tin nhắn SMS đều có thể đăng nhập vào tài khoản bằng số điện thoại của thiết bị.

Nếu bạn sử dụng tính năng đăng nhập dựa trên số điện thoại trong ứng dụng của mình, thì bạn nên cung cấp tính năng này cùng với các phương thức đăng nhập an toàn hơn và thông báo cho người dùng về những đánh đổi bảo mật khi sử dụng tính năng đăng nhập bằng số điện thoại.

Bật đăng nhập Số điện thoại cho dự án Firebase của bạn

Để đăng nhập người dùng bằng SMS, trước tiên bạn phải bật phương thức đăng nhập bằng Số điện thoại cho dự án Firebase của mình:

  1. Trong bảng điều khiển Firebase , hãy mở phần Xác thực .
  2. Trên trang Phương thức đăng nhập , bật phương thức đăng nhập Số điện thoại .
  3. Trên cùng một trang, nếu miền sẽ lưu trữ ứng dụng của bạn không được liệt kê trong phần miền chuyển hướng OAuth , hãy thêm miền của bạn.

Hạn ngạch yêu cầu đăng nhập bằng số điện thoại của Firebase đủ cao để hầu hết các ứng dụng không bị ảnh hưởng. Tuy nhiên, nếu bạn cần đăng nhập một lượng lớn người dùng bằng xác thực qua điện thoại, bạn có thể cần phải nâng cấp gói giá của mình. Xem trang giá cả .

Thiết lập trình xác minh reCAPTCHA

Trước khi bạn có thể đăng nhập người dùng bằng số điện thoại của họ, bạn phải thiết lập trình xác minh reCAPTCHA của Firebase. Firebase sử dụng reCAPTCHA để ngăn chặn hành vi lạm dụng, chẳng hạn như bằng cách đảm bảo rằng yêu cầu xác minh số điện thoại đến từ một trong các miền được phép của ứng dụng của bạn.

Bạn không cần thiết lập ứng dụng khách reCAPTCHA theo cách thủ công; khi bạn sử dụng đối tượng RecaptchaVerifier của SDK Firebase, Firebase sẽ tự động tạo và xử lý mọi khóa và bí mật máy khách cần thiết.

Đối tượng RecaptchaVerifier hỗ trợ reCAPTCHA ẩn , thường có thể xác minh người dùng mà không yêu cầu bất kỳ hành động nào của người dùng, cũng như tiện ích reCAPTCHA, luôn yêu cầu tương tác của người dùng để hoàn tất thành công.

reCAPTCHA được hiển thị cơ bản có thể được bản địa hóa theo tùy chọn của người dùng bằng cách cập nhật mã ngôn ngữ trên phiên bản Auth trước khi hiển thị reCAPTCHA. Bản địa hóa nói trên cũng sẽ áp dụng cho tin nhắn SMS được gửi tới người dùng, có chứa mã xác minh.

Web modular 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 namespaced API

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

Sử dụng reCAPTCHA vô hình

Để sử dụng reCAPTCHA ẩn, hãy tạo một đối tượng RecaptchaVerifier với tham số size được đặt thành invisible , chỉ định ID của nút gửi biểu mẫu đăng nhập của bạn. Ví dụ:

Web modular 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 namespaced API

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

Sử dụng tiện ích reCAPTCHA

Để sử dụng tiện ích reCAPTCHA hiển thị, hãy tạo một thành phần trên trang của bạn để chứa tiện ích, sau đó tạo đối tượng RecaptchaVerifier , chỉ định ID của vùng chứa khi bạn làm như vậy. Ví dụ:

Web modular API

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

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

Web namespaced API

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

Tùy chọn: Chỉ định tham số reCAPTCHA

Bạn có thể tùy ý đặt các hàm gọi lại trên đối tượng RecaptchaVerifier được gọi khi người dùng giải reCAPTCHA hoặc reCAPTCHA hết hạn trước khi người dùng gửi biểu mẫu:

Web modular 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 namespaced API

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

Tùy chọn: Kết xuất trước reCAPTCHA

Nếu bạn muốn hiển thị trước reCAPTCHA trước khi gửi yêu cầu đăng nhập, hãy gọi render :

Web modular API

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

Web namespaced API

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

Sau khi xử lý kết render , bạn nhận được ID tiện ích con của reCAPTCHA mà bạn có thể sử dụng để thực hiện lệnh gọi tới API reCAPTCHA :

Web modular API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web namespaced API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Gửi mã xác minh đến điện thoại của người dùng

Để bắt đầu đăng nhập bằng số điện thoại, hãy cung cấp cho người dùng một giao diện nhắc họ cung cấp số điện thoại của mình, sau đó gọi signInWithPhoneNumber để yêu cầu Firebase gửi mã xác thực đến điện thoại của người dùng bằng SMS:

  1. Lấy số điện thoại của người dùng.

    Các yêu cầu pháp lý khác nhau, nhưng theo phương pháp hay nhất và để đặt kỳ vọng cho người dùng của bạn, bạn nên thông báo cho họ rằng nếu họ sử dụng đăng nhập bằng điện thoại, họ có thể nhận được tin nhắn SMS để xác minh và áp dụng mức phí tiêu chuẩn.

  2. Gọi signInWithPhoneNumber , chuyển đến số điện thoại của người dùng và RecaptchaVerifier mà bạn đã tạo trước đó.

    Web modular 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 namespaced API

    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
          // ...
        });
    Nếu signInWithPhoneNumber gây ra lỗi, hãy đặt lại reCAPTCHA để người dùng có thể thử lại:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

Phương thức signInWithPhoneNumber đưa ra thử thách reCAPTCHA cho người dùng và nếu người dùng vượt qua thử thách, hãy yêu cầu Xác thực Firebase gửi tin nhắn SMS có chứa mã xác minh tới điện thoại của người dùng.

Đăng nhập người dùng bằng mã xác minh

Sau khi cuộc gọi signInWithPhoneNumber thành công, hãy nhắc người dùng nhập mã xác minh mà họ nhận được qua SMS. Sau đó, đăng nhập người dùng bằng cách chuyển mã tới phương thức confirm của đối tượng ConfirmationResult đã được chuyển tới trình xử lý thực hiện của signInWithPhoneNumber (tức là khối then của nó). Ví dụ:

Web modular 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 namespaced 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?)
  // ...
});

Nếu cuộc gọi confirm thành công, người dùng đã đăng nhập thành công.

Lấy đối tượng AuthCredential trung gian

Nếu bạn cần lấy một đối tượng AuthCredential cho tài khoản của người dùng, hãy chuyển mã xác minh từ kết quả xác nhận và mã xác minh tới PhoneAuthProvider.credential thay vì gọi confirm :

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

Sau đó, bạn có thể đăng nhập người dùng bằng thông tin xác thực:

firebase.auth().signInWithCredential(credential);

Thử nghiệm với số điện thoại hư cấu

Bạn có thể thiết lập các số điện thoại hư cấu để phát triển thông qua bảng điều khiển Firebase. Thử nghiệm với các số điện thoại hư cấu mang lại những lợi ích sau:

  • Kiểm tra xác thực số điện thoại mà không tiêu tốn dung lượng sử dụng của bạn.
  • Kiểm tra xác thực số điện thoại mà không gửi tin nhắn SMS thực.
  • Chạy thử nghiệm liên tiếp với cùng một số điện thoại mà không bị điều chỉnh. Điều này giảm thiểu rủi ro bị từ chối trong quá trình đánh giá Cửa hàng ứng dụng nếu người đánh giá tình cờ sử dụng cùng một số điện thoại để thử nghiệm.
  • Thử nghiệm dễ dàng trong môi trường phát triển mà không cần thêm bất kỳ nỗ lực nào, chẳng hạn như khả năng phát triển trong trình giả lập iOS hoặc trình giả lập Android mà không cần Dịch vụ của Google Play.
  • Viết các bài kiểm tra tích hợp mà không bị chặn bởi kiểm tra bảo mật thường được áp dụng trên các số điện thoại thực trong môi trường sản xuất.

Số điện thoại hư cấu phải đáp ứng các yêu cầu sau:

  1. Đảm bảo rằng bạn sử dụng các số điện thoại thực sự hư cấu và chưa tồn tại. Xác thực Firebase không cho phép bạn đặt các số điện thoại hiện có được người dùng thực sử dụng làm số kiểm tra. Một tùy chọn là sử dụng các số có tiền tố 555 làm số điện thoại thử nghiệm ở Hoa Kỳ, ví dụ: +1 650-555-3434
  2. Số điện thoại phải được định dạng chính xác về độ dài và các ràng buộc khác. Chúng vẫn sẽ trải qua quá trình xác thực giống như số điện thoại của người dùng thực.
  3. Bạn có thể thêm tối đa 10 số điện thoại để phát triển.
  4. Sử dụng các số điện thoại/mã kiểm tra khó đoán và thay đổi chúng thường xuyên.

Tạo số điện thoại hư cấu và mã xác minh

  1. Trong bảng điều khiển Firebase , hãy mở phần Xác thực .
  2. Trong tab Phương thức đăng nhập , hãy bật Nhà cung cấp điện thoại nếu bạn chưa bật.
  3. Mở menu Số điện thoại để kiểm tra đàn accordion.
  4. Cung cấp số điện thoại bạn muốn kiểm tra, ví dụ: +1 650-555-3434 .
  5. Cung cấp mã xác minh gồm 6 chữ số cho số cụ thể đó, ví dụ: 654321 .
  6. Thêm số. Nếu có nhu cầu, bạn có thể xóa số điện thoại và mã của nó bằng cách di chuột vào hàng tương ứng và nhấn vào biểu tượng thùng rác.

Kiểm tra bằng tay

Bạn có thể trực tiếp bắt đầu sử dụng một số điện thoại hư cấu trong ứng dụng của mình. Điều này cho phép bạn thực hiện kiểm tra thủ công trong các giai đoạn phát triển mà không gặp phải các vấn đề về hạn ngạch hoặc điều tiết. Bạn cũng có thể kiểm tra trực tiếp từ trình giả lập iOS hoặc trình giả lập Android mà không cần cài đặt Dịch vụ của Google Play.

Khi bạn cung cấp số điện thoại hư cấu và gửi mã xác minh, sẽ không có tin nhắn SMS thực nào được gửi. Thay vào đó, bạn cần cung cấp mã xác minh đã định cấu hình trước đó để hoàn tất đăng nhập.

Khi hoàn tất đăng nhập, người dùng Firebase được tạo bằng số điện thoại đó. Người dùng có hành vi và thuộc tính giống như người dùng số điện thoại thực và có thể truy cập Cơ sở dữ liệu thời gian thực/Cloud Firestore và các dịch vụ khác theo cùng một cách. Mã thông báo ID được đúc trong quá trình này có chữ ký giống như người dùng số điện thoại thực.

Một tùy chọn khác là đặt vai trò thử nghiệm thông qua xác nhận quyền sở hữu tùy chỉnh đối với những người dùng này để phân biệt họ là người dùng giả mạo nếu bạn muốn hạn chế quyền truy cập hơn nữa.

Thử nghiệm hội nhập

Ngoài thử nghiệm thủ công, Xác thực Firebase cung cấp API để giúp viết các thử nghiệm tích hợp cho thử nghiệm xác thực điện thoại. Các API này vô hiệu hóa xác minh ứng dụng bằng cách vô hiệu hóa yêu cầu reCAPTCHA trên web và thông báo đẩy im lặng trong iOS. Điều này làm cho thử nghiệm tự động hóa có thể thực hiện được trong các luồng này và dễ triển khai hơn. Ngoài ra, chúng giúp cung cấp khả năng kiểm tra các luồng xác minh tức thời trên Android.

Trên web, đặt appVerificationDisabledForTesting thành true trước khi hiển thị firebase.auth.RecaptchaVerifier . Thao tác này sẽ tự động giải quyết reCAPTCHA, cho phép bạn chuyển số điện thoại mà không cần giải quyết theo cách thủ công. Lưu ý rằng ngay cả khi reCAPTCHA bị vô hiệu hóa, việc sử dụng số điện thoại không hư cấu vẫn sẽ không thể hoàn tất đăng nhập. Chỉ số điện thoại hư cấu mới có thể được sử dụng với API này.

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

Trình xác minh ứng dụng reCAPTCHA mô phỏng có thể nhìn thấy và không nhìn thấy hoạt động khác nhau khi tính năng xác minh ứng dụng bị tắt:

  • ReCAPTCHA có thể nhìn thấy : Khi reCAPTCHA có thể nhìn thấy được hiển thị qua appVerifier.render() , nó sẽ tự động giải quyết sau một phần giây chậm trễ. Điều này tương đương với việc người dùng nhấp vào reCAPTCHA ngay khi hiển thị. Phản hồi reCAPTCHA sẽ hết hạn sau một thời gian và sau đó tự động phân giải lại.
  • reCAPTCHA ẩn : reCAPTCHA ẩn không tự động phân giải khi kết xuất và thay vào đó, nó tự động phân giải trên lệnh gọi appVerifier.verify() hoặc khi nút liên kết của reCAPTCHA được nhấp sau một phần giây chậm trễ. Tương tự như vậy, phản hồi sẽ hết hạn sau một thời gian và sẽ chỉ tự động giải quyết sau lệnh gọi appVerifier.verify() hoặc khi nút liên kết của reCAPTCHA được nhấp lại.

Bất cứ khi nào một reCAPTCHA giả được giải quyết, chức năng gọi lại tương ứng sẽ được kích hoạt như mong đợi với phản hồi giả. Nếu một cuộc gọi lại hết hạn cũng được chỉ định, nó sẽ kích hoạt khi hết hạn.

Bước tiếp theo

Sau khi người dùng đăng nhập lần đầu tiên, tài khoản người dùng mới được tạo và liên kết với thông tin đăng nhập—nghĩa là tên người dùng và mật khẩu, số điện thoại hoặc thông tin nhà cung cấp xác thực—người dùng đã đăng nhập bằng. Tài khoản mới này được lưu trữ như một phần của dự án Firebase của bạn và có thể được sử dụng để xác định 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 các ứng dụng của bạn, cách được đề xuất để biết trạng thái xác thực của người dùng là đặt một người quan sát trên đối tượng Auth . Sau đó, bạn có thể lấy thông tin hồ sơ cơ bản của người dùng từ đối tượng User . Xem Quản lý người dùng .

  • Trong Cơ sở dữ liệu thời gian thực Firebase và Quy tắc bảo mật bộ lưu trữ đám mây , bạn có thể lấy ID người dùng duy nhất của người dùng đã đăng nhập từ biến auth và sử dụng biến đó để kiểm soát 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 nhà cung cấp xác thực bằng cách liên kết thông tin đăng nhập của nhà cung cấp xác thực với tài khoản người dùng hiện có.

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

Web modular API

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

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

Web namespaced API

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