Yêu cầu xác minh qua SMS trong ứng dụng Android

Để tự động xác minh số điện thoại, bạn phải triển khai cả phần ứng dụng khách và máy chủ của quy trình xác minh. Tài liệu này mô tả cách triển khai phần ứng dụng trong một ứng dụng Android.

Để bắt đầu quy trình xác minh số điện thoại trong một ứng dụng Android, bạn sẽ gửi số điện thoại đến máy chủ xác minh và gọi SMS Retriever API để bắt đầu nghe tin nhắn SMS chứa mã một lần cho ứng dụng của bạn. Sau khi nhận được tin nhắn, bạn sẽ gửi mã một lần đó trở lại máy chủ để hoàn tất quy trình xác minh.

Trước khi bắt đầu

Để chuẩn bị cho ứng dụng của bạn, hãy hoàn tất các bước trong những phần sau.

Điều kiện tiên quyết đối với ứng dụng

Hãy đảm bảo tệp bản dựng của ứng dụng sử dụng các giá trị sau:

  • minSdkVersion từ 19 trở lên
  • compileSdkVersion phiên bản 28 trở lên

Định cấu hình ứng dụng

Trong tệp build.gradle ở cấp dự án, hãy thêm kho lưu trữ Maven của Googlekho lưu trữ trung tâm Maven vào cả hai mục buildscriptallprojects:

buildscript {
    repositories {
        google()
        mavenCentral()
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

Thêm phần phụ thuộc Dịch vụ Google Play dành cho API Trình truy xuất tin nhắn SMS vào tệp bản dựng Gradle của mô-đun, thường là app/build.gradle:

dependencies {
  implementation 'com.google.android.gms:play-services-auth:21.3.0'
  implementation 'com.google.android.gms:play-services-auth-api-phone:18.1.0'
}

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

Bạn có thể lấy số điện thoại của người dùng theo bất kỳ cách nào phù hợp với ứng dụng của mình. Thông thường, trải nghiệm người dùng tốt nhất là sử dụng bộ chọn gợi ý để nhắc người dùng chọn trong số các số điện thoại được lưu trữ trên thiết bị, nhờ đó tránh phải nhập số điện thoại theo cách thủ công. Cách sử dụng bộ chọn gợi ý:

// Construct a request for phone numbers and show the picker
private void requestHint() {
    HintRequest hintRequest = new HintRequest.Builder()
           .setPhoneNumberIdentifierSupported(true)
           .build();

    PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(
            apiClient, hintRequest);
    startIntentSenderForResult(intent.getIntentSender(),
            RESOLVE_HINT, null, 0, 0, 0);
}

// Obtain the phone number from the result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == RESOLVE_HINT) {
      if (resultCode == RESULT_OK) {
          Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
          // credential.getId();  <-- will need to process phone number string
      }
  }
}

2. Bắt đầu trình truy xuất tin nhắn SMS

Khi bạn đã sẵn sàng xác minh số điện thoại của người dùng, hãy lấy một thực thể của đối tượng SmsRetrieverClient, gọi startSmsRetriever và đính kèm trình nghe thành công và không thành công vào tác vụ truy xuất SMS:

// Get an instance of SmsRetrieverClient, used to start listening for a matching
// SMS message.
SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);

// Starts SmsRetriever, which waits for ONE matching SMS message until timeout
// (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
// action SmsRetriever#SMS_RETRIEVED_ACTION.
Task<Void> task = client.startSmsRetriever();

// Listen for success/failure of the start Task. If in a background thread, this
// can be made blocking using Tasks.await(task, [timeout]);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
  @Override
  public void onSuccess(Void aVoid) {
    // Successfully started retriever, expect broadcast intent
    // ...
  }
});

task.addOnFailureListener(new OnFailureListener() {
  @Override
  public void onFailure(@NonNull Exception e) {
    // Failed to start retriever, inspect Exception for more details
    // ...
  }
});

Tác vụ truy xuất tin nhắn SMS sẽ nghe trong tối đa 5 phút để tìm một tin nhắn SMS chứa một chuỗi duy nhất giúp xác định ứng dụng của bạn.

3. Gửi số điện thoại đến máy chủ của bạn

Sau khi bạn lấy được số điện thoại của người dùng và bắt đầu nghe tin nhắn SMS, hãy gửi số điện thoại của người dùng đến máy chủ xác minh bằng bất kỳ phương thức nào (thường là bằng yêu cầu POST HTTPS).

Máy chủ của bạn sẽ tạo một thông báo xác minh và gửi thông báo đó qua SMS đến số điện thoại bạn chỉ định. Xem phần Thực hiện quy trình xác minh qua SMS trên máy chủ.

4. Nhận tin nhắn xác minh

Khi nhận được thông báo xác minh trên thiết bị của người dùng, Dịch vụ Play sẽ truyền phát một Ý định SmsRetriever.SMS_RETRIEVED_ACTION rõ ràng đến ứng dụng của bạn, trong đó chứa văn bản của thông báo. Sử dụng BroadcastReceiver để nhận thông báo xác minh này.

Trong trình xử lý onReceive của BroadcastReceiver, hãy lấy văn bản của tin nhắn xác minh (và địa chỉ người gửi nếu muốn) từ các thông tin bổ sung của Ý định:

/**
 * BroadcastReceiver to wait for SMS messages. This can be registered either
 * in the AndroidManifest or at runtime.  Should filter Intents on
 * SmsRetriever.SMS_RETRIEVED_ACTION.
 */
public class MySMSBroadcastReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
      Bundle extras = intent.getExtras();
      Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);

      switch(status.getStatusCode()) {
        case CommonStatusCodes.SUCCESS:
          // (Optional) Get SMS Sender address - only available in
          // GMS version 24.20 onwards, else it will return null
          String senderAddress = extras.getString(SmsRetriever.EXTRA_SMS_ORIGINATING_ADDRESS);
          // Get SMS message contents
          String message = extras.getString(SmsRetriever.EXTRA_SMS_MESSAGE);
          // Extract one-time code from the message and complete verification
          // by sending the code back to your server.
          break;
        case CommonStatusCodes.TIMEOUT:
          // Waiting for SMS timed out (5 minutes)
          // Handle the error ...
          break;
      }
    }
  }
}

Đăng ký BroadcastReceiver này bằng bộ lọc ý định com.google.android.gms.auth.api.phone.SMS_RETRIEVED (giá trị của hằng số SmsRetriever.SMS_RETRIEVED_ACTION) và quyền com.google.android.gms.auth.api.phone.permission.SEND (giá trị của hằng số SmsRetriever.SEND_PERMISSION) trong tệp AndroidManifest.xml của ứng dụng, như trong ví dụ sau hoặc sử dụng Context.registerReceiver một cách linh động.

<receiver android:name=".MySMSBroadcastReceiver" android:exported="true"
          android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
    </intent-filter>
</receiver>

5. Gửi mã một lần trong thông báo xác minh đến máy chủ của bạn

Bây giờ, bạn đã có văn bản của thông báo xác minh, hãy sử dụng một biểu thức chính quy hoặc một số logic khác để lấy mã một lần từ thông báo. Định dạng của mã một lần phụ thuộc vào cách bạn triển khai mã đó trong máy chủ.

Cuối cùng, hãy gửi mã một lần đến máy chủ của bạn qua một kết nối bảo mật. Khi nhận được mã một lần, máy chủ của bạn sẽ ghi lại rằng số điện thoại đã được xác minh.