Xác thực điện thoại

Tính năng xác thực điện thoại cho phép người dùng đăng nhập vào Firebase bằng điện thoại của họ làm trình xác thực. Một tin nhắn SMS đã được gửi cho người dùng (sử dụng số điện thoại được cung cấp) có chứa mã duy nhất. Sau khi mã được uỷ quyền, người dùng có thể ký vào Firebase.

Số điện thoại mà người dùng cuối cung cấp để xác thực sẽ được Google gửi và lưu trữ để cải thiện thư rác và hành vi sai trái ngăn chặn trên các dịch vụ của Google, bao gồm nhưng không giới hạn ở Firebase. Nhà phát triển phải đảm bảo rằng họ có sự đồng ý thích hợp của người dùng cuối trước khi sử dụng dịch vụ đăng nhập bằng số điện thoại xác thực Firebase.

Tính năng Xác thực bằng điện thoại Firebase không được hỗ trợ ở một số quốc gia. Vui lòng xem phần Câu hỏi thường gặp của họ để biết thêm thông tin.

Thiết lập

Trước khi bắt đầu với tính năng Xác thực điện thoại, hãy đảm bảo rằng bạn đã thực hiện theo các bước sau:

  1. Bật Điện thoại làm phương thức Đăng nhập trong bảng điều khiển của Firebase.
  2. Android: Nếu bạn chưa đặt hàm băm SHA-1 của ứng dụng trong bảng điều khiển của Firebase, hãy thực hiện việc này. Hãy xem bài viết Xác thực ứng dụng của bạn để biết thông tin về cách tìm hàm băm SHA-1 của ứng dụng.
  3. iOS: Trong Xcode, hãy bật thông báo đẩy cho dự án của bạn và đảm bảo khoá xác thực APN của bạn được định cấu hình bằng Giải pháp gửi thông báo qua đám mây của Firebase (FCM). Ngoài ra, bạn phải bật chế độ nền cho thông báo từ xa. Để xem nội dung giải thích chi tiết về bước này, hãy xem tài liệu về Xác thực điện thoại trên iOS của Firebase.
  4. Web: Đảm bảo rằng bạn đã thêm miền ứng dụng của mình trên bảng điều khiển của Firebase, trong Miền chuyển hướng OAuth.

Lưu ý; Tính năng đăng nhập bằng số điện thoại chỉ dùng được trên thiết bị thực và trên web. Để kiểm thử quy trình xác thực trên trình mô phỏng thiết bị, vui lòng xem phần Thử nghiệm.

Cách sử dụng

SDK xác thực Firebase dành cho Flutter cung cấp hai cách riêng biệt để đăng nhập người dùng bằng số điện thoại của họ. Các nền tảng gốc (ví dụ: Android và iOS) cung cấp chức năng xác thực số điện thoại khác với web, do đó có hai phương pháp dành riêng cho mỗi nền tảng:

  • Nền tảng gốc: verifyPhoneNumber.
  • Nền tảng web: signInWithPhoneNumber.

Gốc: verifyPhoneNumber

Trên các nền tảng gốc, trước tiên số điện thoại của người dùng phải được xác minh, sau đó người dùng có thể đăng nhập hoặc liên kết tài khoản của họ với PhoneAuthCredential.

Trước tiên, bạn phải nhắc người dùng cung cấp số điện thoại của họ. Sau khi được cung cấp, hãy gọi phương thức verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

Bạn cần xử lý 4 lệnh gọi lại riêng biệt, mỗi lệnh gọi lại sẽ xác định cách bạn cập nhật giao diện người dùng của ứng dụng:

  1. verificationCompleted: Tự động xử lý mã SMS trên các thiết bị Android.
  2. verificationFailed: Xử lý các sự kiện không thành công, chẳng hạn như số điện thoại không hợp lệ hoặc việc đã vượt quá hạn mức tin nhắn SMS hay chưa.
  3. codeSent: Xử lý khi một mã được gửi đến thiết bị từ Firebase, dùng để nhắc người dùng nhập mã.
  4. codeAutoRetrievalHết thời gian chờ: Xử lý thời gian chờ khi hệ thống không xử lý được mã gửi qua SMS tự động.

Xác minh đã hoàn tất

Trình xử lý này sẽ chỉ được gọi trên các thiết bị Android hỗ trợ tự động phân giải mã SMS.

Khi mã SMS được gửi đến thiết bị, Android sẽ tự động xác minh mã SMS đó mà không yêu cầu người dùng nhập mã theo cách thủ công. Nếu sự kiện này xảy ra, PhoneAuthCredential sẽ được cung cấp tự động và có thể được dùng để đăng nhập hoặc liên kết số điện thoại của người dùng.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

không xác minh được

Nếu Firebase trả về lỗi, ví dụ: số điện thoại không chính xác hoặc nếu đã vượt quá hạn mức tin nhắn SMS cho dự án, một FirebaseAuthException sẽ được gửi đến trình xử lý này. Trong trường hợp này, bạn sẽ nhắc người dùng rằng đã xảy ra lỗi tuỳ thuộc vào lỗi đó .

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

Đã gửi mã

Khi Firebase gửi một mã SMS đến thiết bị, trình xử lý này sẽ được kích hoạt bằng verificationIdresendToken (Một resendToken chỉ được hỗ trợ trên thiết bị Android, thiết bị iOS sẽ luôn trả về giá trị null).

Sau khi được kích hoạt, đã đến lúc cập nhật giao diện người dùng của ứng dụng để nhắc người dùng nhập mã SMS mà họ đang muốn. Sau khi nhập mã SMS, bạn có thể kết hợp ID xác minh với mã SMS để tạo PhoneAuthCredential mới:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

Theo mặc định, Firebase sẽ không gửi lại tin nhắn SMS mới nếu tin nhắn đó đã được gửi gần đây. Tuy nhiên, bạn có thể ghi đè hành vi này bằng cách gọi lại phương thức verifyPhoneNumber kèm theo mã gửi lại cho đối số forceResendingToken. Nếu thành công, tin nhắn SMS sẽ được gửi lại.

Thời gian chờ tự động truy xuất mã

Trên các thiết bị Android hỗ trợ tự động phân giải mã SMS, trình xử lý này sẽ được gọi nếu thiết bị không tự động đã giải quyết tin nhắn SMS trong một khung thời gian nhất định. Sau khi hết khung thời gian, thiết bị sẽ không tìm cách phân giải nữa bất kỳ tin nhắn đến nào.

Theo mặc định, thiết bị sẽ chờ 30 giây. Tuy nhiên, bạn có thể tuỳ chỉnh quá trình này bằng đối số timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

Trang web: signInWithPhoneNumber

Trên các nền tảng web, người dùng có thể đăng nhập bằng cách xác nhận rằng họ có quyền truy cập vào một điện thoại bằng cách nhập mã SMS được gửi đến số điện thoại được cung cấp. Để tăng cường bảo mật và ngăn chặn thư rác, người dùng được yêu cầu chứng minh họ là con người bằng cách hoàn thành một reCAPTCHA của Google tiện ích. Sau khi xác nhận, mã SMS sẽ được gửi.

Theo mặc định, SDK xác thực Firebase dành cho Flutter sẽ quản lý tiện ích reCAPTCHA ngay từ đầu. Tuy nhiên, bạn có thể kiểm soát cách hiển thị và định cấu hình tiện ích này nếu cần. Để bắt đầu, hãy gọi phương thức signInWithPhoneNumber bằng số điện thoại.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

Khi gọi phương thức này, trước tiên, tiện ích reCAPTCHA sẽ hiển thị. Người dùng phải hoàn tất kiểm tra trước khi gửi mã SMS. Sau khi hoàn tất, bạn có thể đăng nhập người dùng bằng cách cung cấp Mã gửi qua SMS đến phương thức confirm trên phản hồi ConfirmationResult đã được giải quyết:

UserCredential userCredential = await confirmationResult.confirm('123456');

Giống như các quy trình đăng nhập khác, việc đăng nhập thành công sẽ kích hoạt mọi trình nghe trạng thái xác thực mà bạn đã đăng ký trong suốt quá trình đăng ký.

Cấu hình reCAPTCHA

Tiện ích reCAPTCHA là một quy trình được quản lý hoàn toàn, giúp cung cấp tính năng bảo mật cho ứng dụng web của bạn.

Đối số thứ hai của signInWithPhoneNumber chấp nhận một thực thể RecaptchaVerifier (không bắt buộc) có thể dùng để quản lý tiện ích này. Theo mặc định, tiện ích này sẽ hiển thị dưới dạng một tiện ích ẩn khi quy trình đăng nhập được kích hoạt. "Ẩn" sẽ xuất hiện dưới dạng cửa sổ toàn trang ở đầu ứng dụng.

Tuy nhiên, bạn có thể hiển thị một tiện ích cùng dòng mà người dùng phải nhấn một cách rõ ràng để xác minh chính mình.

Để thêm một tiện ích cùng dòng, hãy chỉ định một mã phần tử DOM cho đối số container của thực thể RecaptchaVerifier. Phần tử phải tồn tại và để trống, nếu không sẽ xảy ra lỗi. Nếu bạn không cung cấp đối số container, thì tiện ích sẽ hiển thị dưới dạng "invisible".

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

Bạn có thể tuỳ ý thay đổi kích thước và giao diện bằng cách tuỳ chỉnh các đối số sizetheme như trình bày ở trên.

Bạn cũng có thể theo dõi các sự kiện, chẳng hạn như liệu người dùng đã hoàn tất reCAPTCHA hay chưa, cho dù reCAPTCHA đã hết hạn hoặc có lỗi được gửi:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

Thử nghiệm

Firebase hỗ trợ các số điện thoại thử nghiệm cục bộ:

  1. Trong Bảng điều khiển của Firebase, hãy chọn "Điện thoại" nhà cung cấp dịch vụ xác thực và nhấp vào "Số điện thoại để kiểm tra" trình đơn thả xuống.
  2. Nhập số điện thoại mới (ví dụ: +44 7444 555666) và mã thử nghiệm (ví dụ: 123456).

Nếu bạn cung cấp số điện thoại thử nghiệm cho phương thức verifyPhoneNumber hoặc signInWithPhoneNumber, thì sẽ không có tin nhắn SMS nào thực sự được gửi. Bạn thay vào đó có thể cung cấp mã kiểm thử trực tiếp cho PhoneAuthProvider hoặc thông qua trình xử lý kết quả xác nhận của signInWithPhoneNumber.