בקשת אימות באמצעות 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.0.0'
  implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.2'
}

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

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

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

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

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

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

ב-handler של onReceive ב-BroadcastReceiver, מקבלים את הטקסט של הודעת האימות מהתוספות של ה-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:
          // Get SMS message contents
          String message = (String) extras.get(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. שליחת קוד חד-פעמי מהודעת האימות לשרת שלך

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

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