Bạn có thể 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ả vào triển khai quy trình đăng nhập để đă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 liên kết. 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 Firebase SDK.
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 tạo 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 sẽ kém an toàn hơn so với các phương thức khác hiện có, vì quyền sở hữu số điện thoại có thể dễ dàng chuyển giao giữa 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ề những điểm đá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.
- Không bắt buộc: Trên trang Cài đặt, hãy đặt một chính sách về những khu vực mà bạn muốn cho phép hoặc từ chối gửi tin nhắn SMS. Việc thiết lập chính sách về khu vực gửi SMS có thể giúp bảo vệ ứng dụng của bạn khỏi hành vi sai trái qua SMS.
- Trên cùng trang, nếu miền sẽ lưu trữ ứng dụng của bạn không có trong phần 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 dùng máy chủ lưu trữ cục bộ làm miền được lưu trữ cho mục đích xác thực bằng đ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 những miền được phép của ứng dụng.
Bạn không cần thiết lập thủ công một ứng dụng reCAPTCHA; khi bạn sử dụng đối tượng RecaptchaVerifier
của Firebase SDK, Firebase sẽ tự động tạo và xử lý mọi khoá và bí mật cần thiết của ứng dụng.
Đối tượng RecaptchaVerifier
hỗ trợ reCAPTCHA ẩn. Đối tượng này 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ỳ thao tác 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 được kết xuất 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 kết xuất reCAPTCHA. Quy trình bản địa hoá nêu trên cũng sẽ áp dụng cho tin nhắn SMS chứa mã xác minh được gửi đến người dùng.
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
có tham 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ác hàm này sẽ đượ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
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ã nhận dạng tiện ích của reCAPTCHA. Bạn có thể dùng mã này để gọi 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 quy trình đăng nhập bằng số điện thoại, hãy cho người dùng thấy 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ý có thể khác nhau, 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ả cước phí tiêu chuẩn.
- Gọi
signInWithPhoneNumber
, truyền cho 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
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
sẽ đưa ra thử thách reCAPTCHA cho người dùng và nếu người dùng vượt qua thử thách này, phương thức sẽ 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 đó, hãy đăng nhập người dùng bằng cách truyền mã đến phương thức confirm
của đối tượng ConfirmationResult
đã được truyền đến trình xử lý thực hiện yêu cầu của signInWithPhoneNumber
(tức là khối then
của đối tượng đó). 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.
Nhận đố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 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 cho 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 ảo
Bạn có thể thiết lập số điện thoại ảo để 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 ảo mang lại những lợi ích sau:
- Kiểm thử tính năng xác thực bằng số điện thoại mà không tiêu tốn hạn mức sử dụng.
- Kiểm thử quy trình 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 quy trình xem xét của Cửa hàng ứng dụng nếu người đánh giá vô tình sử dụng cùng một số điện thoại để kiểm thử.
- Dễ dàng kiểm thử trong môi trường phát triển mà không cần nỗ lực thêm, 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 các 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 được áp dụng trên số điện thoại thực trong môi trường sản xuất.
Số điện thoại ảo 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 hoàn toàn là số ảo 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ố thử nghiệm. Một lựa chọn là sử dụng số điện thoại thử nghiệm ở Hoa Kỳ có tiền tố 555, 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 ràng buộc khác. Chúng vẫn sẽ trải qua quy trình xác thực tương tự 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ã kiểm thử khó đoán và thay đổi thường xuyên.
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 điện thoại nếu bạn chưa bật.
- Mở trình đơn dạng bảng 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ã của số điện thoại đó bằng cách di chuột lên 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 trực tiếp một số điện thoại ảo 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 điều tiết. Bạn cũng có thể kiểm thử ngay trên 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 giả 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 quy trình đăng nhập.
Sau khi hoàn tất quá trình đăng nhập, một người dùng Firebase sẽ đượ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, đồng thời có thể truy cập vào Realtime Database/Cloud Firestore và các dịch vụ khác theo cách tương tự. Mã nhận dạng mã thông báo được tạo trong quy trình này có cùng chữ ký với người dùng số điện thoại thực.
Một lựa chọn khác là thiết lập vai trò kiểm thử thông qua các 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ọ với tư cách 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 kiểm thử thủ công, Firebase Authentication còn cung cấp các API giúp bạn viết quy trình kiểm thử tích hợp để kiểm thử tính năng xác thực bằng điện thoại. Các API này vô hiệu hoá quy trình xác minh ứng dụng bằng cách vô hiệu hoá yêu cầu reCAPTCHA trong thông báo đẩy im lặng và trên web trong iOS. Điều này giúp bạn có thể kiểm thử tự động trong các quy trình này và dễ dàng triển khai hơn. Ngoài ra, các API này còn giúp bạn có thể 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 reCAPTCHA, cho phép bạn vượt qua bước xác minh số điện thoại mà không cần giải theo cách thủ công. Xin lưu ý rằng ngay cả khi reCAPTCHA bị vô hiệu hoá, việc sử dụng số điện thoại không phải là số ảo vẫn không thể hoàn tất quá trình đăng nhập. Bạn chỉ có thể sử dụng số điện thoại ảo 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 hiển thị và không hiển thị có hành vi 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 kết xuất thông qua
appVerifier.render()
, reCAPTCHA sẽ tự động giải quyết sau một khoảng thời gian trễ ngắn. Điều này tương đương với việc người dùng nhấp vào reCAPTCHA ngay khi reCAPTCHA hiển thị. Phản hồi reCAPTCHA sẽ hết hạn sau một khoảng thời gian và sau đó tự động giải quyết lại. - Invisible reCAPTCHA: Invisible reCAPTCHA không tự động phân giải khi kết xuất mà sẽ phân giải khi
appVerifier.verify()
gọi hoặc khi người dùng nhấp vào nút neo của reCAPTCHA sau một khoảng trễ ngắn. Tương tự, phản hồi sẽ hết hạn sau một khoảng thời gian và sẽ chỉ tự động giải quyết sau lệnh gọiappVerifier.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 mô phỏng được phân giải, hàm gọi lại tương ứng sẽ được kích hoạt như dự kiến bằng phản hồi giả. Nếu bạn cũng chỉ định một lệnh gọi lại 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 tiên, 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 đăng nhập (tức 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 dịch vụ uỷ quyền) mà người dùng đã đăng nhập. Tài khoản mới này được lưu trữ trong dự án Firebase của bạn và có thể dùng để xác định một người dùng trên mọi ứng dụng trong dự á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 hay nhất để biết trạng thái uỷ quyền của người dùng là đặt một đối tượng theo dõi 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 Firebase Realtime Database và Cloud Storage Quy tắc bảo mật, bạn có thể lấy mã nhận dạng người dùng riêng biệt của người dùng đã đăng nhập từ biến
auth
và dùng mã nhận dạng này để 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 đăng nhập 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. });