בקשת אימות באמצעות SMS באפליקציה ל-Android

כדי לאמת מספרי טלפון באופן אוטומטי, עליך ליישם גם את הלקוח וגם את חלקי השרת בתהליך האימות. במסמך הזה נסביר איך להטמיע את חלק הלקוח באפליקציה ל-Android.

כדי להתחיל את תהליך האימות של מספר הטלפון באפליקציה ל-Android, צריך לשלוח את עם מספר הטלפון של שרת האימות שלך, וקוראים לממשק ה-API של SMS Retriever כדי להתחיל האזנה להודעת SMS שמכילה קוד חד-פעמי לאפליקציה שלך. אחרי מקבלים את ההודעה, שולחים את הקוד החד-פעמי בחזרה לשרת כדי להשלים את הפעולה תהליך האימות.

לפני שמתחילים

כדי להכין את האפליקציה, צריך לבצע את השלבים בקטעים הבאים.

דרישות מוקדמות לאפליקציה

יש לוודא שקובץ ה-build של האפליקציה משתמש בערכים הבאים:

  • גרסת minSdkVersion 19 ואילך
  • גרסת compileSdkVersion של 28 ואילך

הגדרת האפליקציה

בקובץ build.gradle ברמת הפרויקט, כוללים את מאגר Maven של Google ובמאגר המרכזי של Maven בקטע buildscript ו-allprojects:

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

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

הוספת התלות של Google Play Services ל-SMS Retriever API אל קובץ ה-build של 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. הפעלת הכלי לאחזור ה-SMS

כשתהיו מוכנים לאמת את מספר הטלפון של המשתמש, קבלו מופע של אובייקט 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 תאזין במשך חמש דקות לכל היותר עבור הודעת SMS שמכיל מחרוזת ייחודית שמזהה את האפליקציה שלכם.

3. שליחת מספר הטלפון לשרת

אחרי שמקבלים את מספר הטלפון של המשתמש ומתחילים להאזין ל-SMS הודעות, שלח את מספר הטלפון של המשתמש לשרת האימות שלך באמצעות (בדרך כלל באמצעות בקשת HTTPS POST).

השרת יוצר הודעת אימות ושולח אותה לטלפון ב-SMS המספר שציינת. למידע נוסף, ראו ביצוע אימות SMS בשרת.

4. לקבל הודעות אימות

כשמתקבלת הודעת אימות במכשיר של המשתמש, Play Services משדרת באופן מפורש לאפליקציה שלכם Intent SmsRetriever.SMS_RETRIEVED_ACTION, שמכיל את הטקסט של ההודעה. משתמשים ב-BroadcastReceiver כדי לקבל את הודעת האימות הזו.

ב-handler של BroadcastReceiver onReceive, מקבלים את הטקסט של הודעת אימות (ואופציונלית גם כתובת השולח) מה-Intent תוספות:

/**
 * 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 באמצעות מסנן Intent 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. שליחה של הקוד החד-פעמי מהודעת האימות לשרת שלכם

עכשיו, אחרי שקיבלתם את הטקסט של הודעת האימות, השתמשו בביטוי רגולרי או לוגיקה אחרת לקבלת הקוד החד-פעמי מההודעה. הפורמט של קוד חד-פעמי תלוי באופן שבו הטמעתם אותם בשרת שלכם.

בסוף, יש לשלוח את הקוד החד-פעמי לשרת שלכם דרך חיבור מאובטח. מתי השרת מקבל את הקוד החד-פעמי, הוא מתעד שמספר הטלפון אומת.