طلب إثبات الملكية عبر الرسائل القصيرة SMS في تطبيق Android

لإثبات ملكية أرقام الهواتف تلقائيًا، يجب تنفيذ كل من حساب العميل الأجزاء من عملية إثبات الملكية. تصف هذه الوثيقة كيفية تنفيذ جزء العميل في تطبيق Android.

لبدء عملية إثبات ملكية رقم الهاتف في أحد تطبيقات Android، يجب إرسال رقم الهاتف إلى خادم التحقق والاتصال بواجهة برمجة تطبيقات SMS Retriever API للبدء الاستماع إلى رسالة SMS تحتوي على رمز يُستخدم لمرة واحدة لتطبيقك بعد تتلقى الرسالة، فأنت ترسل الرمز الذي يُستخدم لمرة واحدة إلى خادمك لإكمال عملية التحقق.

قبل البدء

لإعداد تطبيقك، أكمِل الخطوات الواردة في الأقسام التالية.

المتطلّبات الأساسية للتطبيق

يُرجى التأكُّد من أنّ ملف الإصدار لتطبيقك يستخدم القيم التالية:

  • الإصدار 19 من حزمة minSdkVersion أو الإصدارات الأعلى
  • الإصدار 28 أو إصدار أعلى منcom SQLSdkVersion

إعداد تطبيقك

في ملف create.gradle على مستوى المشروع، أضِف مستودع Maven من Google. ومستودع Maven المركزي في كل من القسمين buildscript وallprojects:

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

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

إضافة الاعتمادية على خدمات Google Play لواجهة برمجة التطبيقات SMS Retriever API إلى ملف إصدار Gradle للوحدة، الذي يكون عادةً app/build.gradle:

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

1. الحصول على رقم هاتف المستخدم

يمكنك الحصول على رقم هاتف المستخدم بأي طريقة تناسب التطبيق. غالبًا ما تكون أفضل تجربة للمستخدم هي استخدام منتقي التلميحات لطلب المستخدم للاختيار من بين أرقام الهواتف المخزنة على الجهاز وبالتالي تجنب الاضطرار إلى كتابة رقم الهاتف يدويًا. لاستخدام أداة اختيار التلميحات:

// 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. بدء أداة استرداد الرسائل القصيرة

عندما تكون مستعدًا للتحقق من رقم هاتف المستخدم، احصل على نسخة من عنصر SmsRetrieverClient، الاتصال برقم startSmsRetriever، وإرفاق النتائج بنجاح فشل المستمعين إلى مهمة استرداد الرسائل القصيرة 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
    // ...
  }
});

سيتم معالجة مهمة استرداد الرسائل القصيرة SMS لمدة تصل إلى خمس دقائق يحتوي على سلسلة فريدة تُعرِّف تطبيقك

3- إرسال رقم الهاتف إلى خادمك

بعد حصولك على رقم هاتف المستخدم وبدء الاستماع إلى الرسائل القصيرة SMS الرسائل، يمكنك إرسال رقم هاتف المستخدم إلى خادم التحقق باستخدام (عادةً مع طلب HTTPS POST).

ينشئ الخادم رسالة تحقق ويرسلها إلى الهاتف عبر الرسائل القصيرة SMS. الرقم الذي حددته. راجِع إجراء التحقُّق من خلال الرسائل القصيرة SMS على الخادم.

4. تلقّي رسائل إثبات الهوية

عند استلام رسالة تحقُّق على جهاز المستخدم، تشير "خدمات Play" إلى الإعلان بشكل صريح إلى تطبيقك بهدف SmsRetriever.SMS_RETRIEVED_ACTION Intent الذي يحتوي على نص الرسالة. استخدِم BroadcastReceiver لاستلام رسالة التحقق هذه.

في معالج onReceive الخاص بـ BroadcastReceiver، يمكنك الحصول على نص (وعنوان المرسل بشكل اختياري) من أهداف المزايا الإضافية:

/**
 * 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;
      }
    }
  }
}

سجِّل BroadcastReceiver باستخدام فلتر الأهداف. com.google.android.gms.auth.api.phone.SMS_RETRIEVED (قيمة ثابت SmsRetriever.SMS_RETRIEVED_ACTION) والإذن com.google.android.gms.auth.api.phone.permission.SEND (قيمة SmsRetriever.SEND_PERMISSION ثابت) في AndroidManifest.xml الخاص بتطبيقك كما في المثال التالي، أو ديناميكيًا باستخدام Context.registerReceiver.

<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- إرسال الرمز الذي يُستخدم لمرة واحدة من رسالة إثبات الملكية إلى خادمك

الآن وقد حصلت على نص رسالة التحقق، استخدم تعبيرًا عاديًا أو أي منطق آخر للحصول على الرمز الذي يُستخدم لمرة واحدة من الرسالة. يمثل تنسيق تعتمد الشفرة التي تُستخدم مرة واحدة على كيفية تنفيذها في الخادم.

أخيرًا، أرسل الرمز الذي يُستخدم لمرة واحدة إلى خادمك عبر اتصال آمن. فعندما خادمك الرمز الذي يُستخدم لمرة واحدة، فإنه يسجل أن رقم الهاتف تم التحقق منه.