Bạn có thể sử dụng Firebase Authentication để đăng nhập cho 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 tính năng đăng nhập bằng số điện thoại vào ứng dụng là sử dụng FirebaseUI. FirebaseUI bao gồm một tiện ích đăng nhập thả xuống triển khai quy trình đăng nhập bằng số điện thoại, cũng như đăng nhập liên kết và đăng nhập dựa trên mật khẩu. 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 thực hiện, hãy sao chép đoạn mã khởi chạy từ bảng điều khiển Firebase vào dự án của bạn như mô tả trong phần Thêm Firebase vào dự án JavaScript.Các mối lo ngại về bảo mật
Mặc dù thuận tiện, nhưng việc xác thực chỉ bằng số điện thoại lại kém an toàn hơn so với các phương thức hiện có khác, vì quyền sở hữu số điện thoại có thể dễ dàng được chuyển giữa các 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 một tài khoản bằng số điện thoại của thiết bị.
Nếu sử dụng phương thức đăng nhập dựa trên số điện thoại trong ứng dụng, bạn nên cung cấp phương thức 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ề sự đánh đổi về bảo mật khi sử dụng phương thức đăng nhập bằng số điện thoại.
Bật tính năng Đăng nhập bằng số điện thoại cho dự án Firebase
Để đă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:
- Trong bảng điều khiển Firebase, hãy mở mục Xác thực.
- Trên trang Phương thức đăng nhập, hãy bật phương thức đăng nhập bằng Số điện thoại.
- Trên cùng một trang, nếu miền lưu trữ ứng dụng của bạn không có trong mục Miền chuyển hướng OAuth, hãy thêm miền của bạn. Xin lưu ý rằng bạn không được phép sử dụng máy chủ nội bộ làm miền được lưu trữ cho mục đích xác thực qua điện thoại.
Thiết lập trình xác minh reCAPTCHA
Trước khi có thể đăng nhập người dùng bằng số điện thoại, 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 sai trái, 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.
Bạn không cần thiết lập ứng dụng 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 khoá và bí mật ứng dụng 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 người dùng thực hiện bất kỳ hành động nào, cũng như tiện ích reCAPTCHA luôn yêu cầu người dùng tương tác để hoàn tất thành công.
Bạn có thể bản địa hoá reCAPTCHA hiển thị cơ bản theo lựa chọn ưu tiên của người dùng bằng cách cập nhật mã ngôn ngữ trên thực thể Auth trước khi hiển thị reCAPTCHA. Việc bản địa hoá nêu trên cũng sẽ áp dụng cho tin nhắn SMS được gửi đến người dùng, chứa mã xác minh.
Web
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
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 vô hình, hãy tạo một đối tượng RecaptchaVerifier
với thông số size
được đặt thành invisible
, chỉ định mã nhận dạng của nút gửi biểu mẫu đăng nhập. Ví dụ:
Web
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
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 phần tử trên trang của bạn để chứa tiện ích đó, sau đó tạo một đối tượng RecaptchaVerifier
, chỉ định mã nhận dạng của vùng chứa khi bạn thực hiện việc này. Ví dụ:
Web
import { getAuth, RecaptchaVerifier } from "firebase/auth"; const auth = getAuth(); window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});
Web
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
Không bắt buộc: Chỉ định các thông số reCAPTCHA
Bạn có thể tuỳ ý đặ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 quyết reCAPTCHA hoặc reCAPTCHA hết hạn trước khi người dùng gửi biểu mẫu:
Web
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
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. // ... } });
Không bắt buộc: Kết xuất trước reCAPTCHA
Nếu bạn muốn kết xuất trước reCAPTCHA trước khi gửi yêu cầu đăng nhập, hãy gọi render
:
Web
recaptchaVerifier.render().then((widgetId) => { window.recaptchaWidgetId = widgetId; });
Web
recaptchaVerifier.render().then((widgetId) => { window.recaptchaWidgetId = widgetId; });
Sau khi render
phân giải, bạn sẽ nhận được mã tiện ích của reCAPTCHA. Bạn có thể sử dụng mã này để thực hiện lệnh gọi đến API reCAPTCHA:
Web
const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);
Web
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 hiển thị cho người dùng một giao diện nhắc họ cung cấp số điện thoại, 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 qua SMS:
-
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 tuỳ theo quốc gia, nhưng theo phương pháp hay nhất và để đặt ra kỳ vọng cho người dùng, bạn nên thông báo cho họ rằng nếu sử dụng tính năng đăng nhập bằng điện thoại, họ có thể nhận được tin nhắn SMS để xác minh và sẽ phải trả mức phí tiêu chuẩn.
- Gọi
signInWithPhoneNumber
, truyền vào đó số điện thoại của người dùng vàRecaptchaVerifier
mà bạn đã tạo trước đó.Web
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
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
dẫn đến 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 Firebase Authentication gửi một tin nhắn SMS chứa mã xác minh đến điện thoại của người dùng.
Đăng nhập cho người dùng bằng mã xác minh
Sau khi lệnh gọi đến 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 truyền mã vào phương thức confirm
của đối tượng ConfirmationResult
đã được truyền vào trình xử lý thực hiện của signInWithPhoneNumber
(tức là khối then
của trình xử lý thực hiện). Ví dụ:
Web
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
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 lệnh gọi đến confirm
thành công, người dùng sẽ đăng nhập thành công.
Lấy đối tượng AuthCredential trung gian
Nếu bạn cần lấy đối tượng AuthCredential
cho tài khoản của người dùng, hãy truyền mã xác minh từ kết quả xác nhận và mã xác minh đến 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);
Kiểm thử bằng số điện thoại hư cấu
Bạn có thể thiết lập số điện thoại hư cấu để phát triển thông qua bảng điều khiển Firebase. Việc kiểm thử bằng số điện thoại giả mang lại các lợi ích sau:
- Kiểm thử tính năng xác thực số điện thoại mà không làm hao tổn hạn mức sử dụng.
- Kiểm thử tính năng xác thực số điện thoại mà không cần gửi tin nhắn SMS thực tế.
- Chạy các bài kiểm thử liên tiếp bằng cùng một số điện thoại mà không bị điều tiết. Điều này giúp giảm thiểu nguy cơ bị từ chối trong quá trình xem xét của Cửa hàng ứng dụng nếu người đánh giá sử dụng cùng một số điện thoại để kiểm thử.
- Kiểm thử 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 mô phỏng iOS hoặc trình mô phỏng Android mà không cần Dịch vụ Google Play.
- Viết mã kiểm thử tích hợp mà không bị chặn bởi các quy trình kiểm tra bảo mật thường áp dụng cho 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:
- Đảm bảo rằng bạn sử dụng số điện thoại thực sự là hư cấu và chưa tồn tại. Firebase Authentication không cho phép bạn đặt số điện thoại hiện có mà người dùng thực sử dụng làm số điện thoại thử nghiệm. Bạn có thể sử dụng số điện thoại có tiền tố 555 làm số điện thoại thử nghiệm ở Hoa Kỳ, ví dụ: +1 650-555-3434
- Số điện thoại phải được định dạng chính xác về độ dài và các quy tắc ràng buộc khác. Các số điện thoại này vẫn sẽ trải qua quy trình xác thực giống như số điện thoại của người dùng thực.
- Bạn có thể thêm tối đa 10 số điện thoại để phát triển.
- Sử dụng số điện thoại/mã thử nghiệm khó đoán và thường xuyên thay đổi.
Tạo số điện thoại và mã xác minh giả
- Trong bảng điều khiển Firebase, hãy mở mục Xác thực.
- Trong thẻ Phương thức đăng nhập, hãy bật Nhà cung cấp dịch vụ điện thoại nếu bạn chưa bật.
- Mở trình đơn dạng xếp Số điện thoại để kiểm thử.
- Cung cấp số điện thoại bạn muốn kiểm tra, ví dụ: +1 650-555-3434.
- Cung cấp mã xác minh gồm 6 chữ số cho số điện thoại cụ thể đó, ví dụ: 654321.
- Thêm số điện thoại. Nếu cần, bạn có thể xoá số điện thoại và mã số điện thoại bằng cách di chuột qua hàng tương ứng rồi nhấp vào biểu tượng thùng rác.
Kiểm thử thủ công
Bạn có thể bắt đầu sử dụng 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 thử thủ công trong các giai đoạn phát triển mà không gặp phải vấn đề về hạn mức hoặc bị điều tiết. Bạn cũng có thể kiểm thử trực tiếp từ trình mô phỏng iOS hoặc trình mô phỏng Android mà không cần cài đặt Dịch vụ Google Play.
Khi bạn cung cấp số điện thoại hư cấu và gửi mã xác minh, hệ thống sẽ không gửi tin nhắn SMS thực tế. 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 quy trình đăng nhập.
Khi hoàn tất quy trình đăng nhập, hệ thống sẽ tạo một người dùng Firebase bằng số điện thoại đó. Người dùng này 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 vào Realtime Database/Cloud Firestore cũng như các dịch vụ khác theo cách tương tự. Mã thông báo nhận dạng được tạo trong quá trình này có chữ ký giống với người dùng số điện thoại thực.
Một cách khác là thiết lập vai trò thử nghiệm thông qua thông báo xác nhận quyền sở hữu tuỳ chỉnh cho 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ế thêm quyền truy cập.
Kiểm thử tích hợp
Ngoài việc kiểm thử thủ công, Firebase Authentication còn cung cấp các API để giúp viết mã kiểm thử tích hợp cho việc kiểm thử xác thực qua điện thoại. Các API này tắt tính năng xác minh ứng dụng bằng cách tắt yêu cầu reCAPTCHA trong web và thông báo đẩy thầm trong iOS. Điều này giúp bạn có thể kiểm thử tự động trong các luồng này và dễ triển khai hơn. Ngoài ra, các lớp này còn giúp bạn kiểm thử quy trình xác minh tức thì trên Android.
Trên web, hãy đặ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 truyền số điện thoại mà không cần giải quyết theo cách thủ công. Xin lưu ý rằng mặc dù reCAPTCHA bị tắt, nhưng việc sử dụng số điện thoại không phải là số điện thoại giả vẫn sẽ không hoàn tất được quy trình đăng nhập. Bạn chỉ có thể sử dụng số điện thoại hư cấu 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 giả lập hiển thị và không hiển thị sẽ hoạt động theo cách khác nhau khi tính năng xác minh ứng dụng bị tắt:
- reCAPTCHA hiển thị: Khi reCAPTCHA hiển thị được hiển thị thông qua
appVerifier.render()
, reCAPTCHA này sẽ tự động phân giải sau một khoảng thời gian trễ vài phần trăm giây. Đ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 khoảng thời gian rồi tự động phân giải lại. - Invisible reCAPTCHA: reCAPTCHA vô hình không tự động phân giải khi hiển thị mà sẽ phân giải trên lệnh gọi
appVerifier.verify()
hoặc khi người dùng nhấp vào neo nút của reCAPTCHA sau một khoảng thời gian trễ vài phần trăm giây. Tương tự, phản hồi sẽ hết hạn sau một khoảng thời gian và chỉ tự động phân giải sau lệnh gọiappVerifier.verify()
hoặc khi người dùng nhấp lại vào neo nút của reCAPTCHA.
Bất cứ khi nào một reCAPTCHA giả được phân giải, hàm gọi lại tương ứng sẽ được kích hoạt như dự kiến với phản hồi giả. Nếu bạn cũng chỉ định lệnh gọi lại khi hết hạn, thì lệnh gọi lại đó sẽ kích hoạt khi hết hạn.
Các bước tiếp theo
Sau khi người dùng đăng nhập lần đầu, một tài khoản người dùng mới sẽ được tạo và liên kết với thông tin xác thực (tức là tên người dùng và mật khẩu, số điện thoại hoặc thông tin về nhà cung cấp dịch vụ xác thực) mà người dùng đã đăng nhập. Tài khoản mới này được lưu trữ trong dự án Firebase và có thể được dùng để xác định người dùng trên mọi ứng dụng trong dự án, bất kể người dùng đăng nhập như thế nào.
-
Trong ứng dụng, bạn nên biết trạng thái xác thực của người dùng bằng cách đặt trình 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ượngUser
. Xem phần Quản lý người dùng. Trong Quy tắc bảo mật Firebase Realtime Database và Cloud Storage, 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
và sử dụng mã nhận dạng đó để 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 bạn bằng nhiều trình cung cấp dịch vụ xác thực bằng cách liên kết thông tin xác thực của trình cung cấp dịch vụ xác thực với một tài khoản người dùng hiện có.
Để đăng xuất người dùng, hãy gọi
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. });