SMS-Verifizierung in einer Android-App anfordern

Um Telefonnummern automatisch zu überprüfen, müssen Sie sowohl den Client- als auch den Serverteil des Überprüfungsablaufs implementieren. In diesem Dokument wird beschrieben, wie Sie den Clientteil in einer Android-App implementieren.

Um den Ablauf der Telefonnummernüberprüfung in einer Android-App zu starten, senden Sie die Telefonnummer an Ihren Verifizierungsserver und rufen die SMS Retriever API auf, um eine SMS-Nachricht abzuhören, die einen Einmalcode für Ihre App enthält. Nachdem Sie die Nachricht erhalten haben, senden Sie den Einmalcode an Ihren Server zurück, um den Verifizierungsprozess abzuschließen.

Bevor Sie beginnen

Führen Sie die Schritte in den folgenden Abschnitten aus, um Ihre App vorzubereiten.

App-Voraussetzungen

Stellen Sie sicher, dass die Build-Datei Ihrer App die folgenden Werte verwendet:

  • Eine minSdkVersion von 19 oder höher
  • Eine compilSdkVersion von 28 oder höher

Konfigurieren Sie Ihre App

In Ihrer Projektebene build.gradle Datei enthält Googles Maven - buildscript allprojects Repository und Maven zentrale Repository sowohl Ihre buildscript und allprojects Sektionen:

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

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

Fügen Sie die Google Play - app/build.gradle Dienste Abhängigkeit für den SMS - Retriever - API Ihre Moduls Gradle Build - Datei , die häufig ist app/build.gradle :

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

1. Rufen Sie die Telefonnummer des Benutzers ab

Sie können die Telefonnummer des Benutzers auf jede für Ihre App geeignete Weise abrufen. Oft ist es die beste Benutzererfahrung, die Hinweisauswahl zu verwenden, um den Benutzer aufzufordern, aus den auf dem Gerät gespeicherten Telefonnummern auszuwählen, und dadurch die manuelle Eingabe einer Telefonnummer zu vermeiden. So verwenden Sie die Hinweisauswahl:

// 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. Starten Sie den SMS-Retriever

Wenn Sie bereit sind , die Benutzer-Telefonnummer zu überprüfen, eine Instanz des bekommen SmsRetrieverClient Objekt, rufen startSmsRetriever und bringen Zuhörer Erfolg und Misserfolg auf die SMS - Retrieval - Aufgabe:

// 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
    // ...
  }
});

Die SMS-Abrufaufgabe wartet bis zu fünf Minuten lang auf eine SMS-Nachricht, die eine eindeutige Zeichenfolge enthält, die Ihre App identifiziert.

3. Senden Sie die Telefonnummer an Ihren Server

Nachdem Sie die Telefonnummer des Benutzers erhalten und mit dem Abhören von SMS-Nachrichten begonnen haben, senden Sie die Telefonnummer des Benutzers mit einer beliebigen Methode (normalerweise mit einer HTTPS-POST-Anfrage) an Ihren Verifizierungsserver.

Ihr Server generiert eine Bestätigungsnachricht und sendet diese per SMS an die von Ihnen angegebene Telefonnummer. Siehe Perform SMS - Bestätigung auf dem Server .

4. Bestätigungsnachrichten erhalten

Wenn eine Bestätigungsnachricht auf dem Gerät des Benutzers empfangen wird, Play - Dienste senden explizit auf Ihre Anwendung eines SmsRetriever.SMS_RETRIEVED_ACTION Intent, die den Text der Nachricht enthält. Verwenden Sie eine BroadcastReceiver diese Bestätigungsnachricht zu empfangen.

In der BroadcastReceiver ‚s onReceive Handler, erhält den Text der Bestätigungsnachricht von der Absicht des Extra:

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

Registrieren Sie dieses BroadcastReceiver mit der Absicht Filter com.google.android.gms.auth.api.phone.SMS_RETRIEVED (der Wert der SmsRetriever.SMS_RETRIEVED_ACTION konstant) und die Erlaubnis com.google.android.gms.auth.api.phone.permission.SEND (der Wert der SmsRetriever.SEND_PERMISSION konstante) in Ihrer App AndroidManifest.xml Datei, wie im folgenden Beispiel, oder mit dynamisch 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. Senden Sie den Einmalcode aus der Bestätigungsnachricht an Ihren Server

Nachdem Sie nun den Text der Bestätigungsnachricht haben, verwenden Sie einen regulären Ausdruck oder eine andere Logik, um den Einmalcode aus der Nachricht abzurufen. Das Format des Einmalcodes hängt davon ab, wie Sie ihn in Ihrem Server implementiert haben.

Senden Sie abschließend den Einmalcode über eine sichere Verbindung an Ihren Server. Wenn Ihr Server den Einmalcode empfängt, zeichnet er auf, dass die Telefonnummer verifiziert wurde.

Optional: Telefonnummer mit Smart Lock für Passwörter speichern

Optional können Sie, nachdem der Benutzer seine Telefonnummer verifiziert hat, den Benutzer auffordern, dieses Telefonnummernkonto mit Smart Lock for Passwords zu speichern, damit es automatisch in anderen Apps und auf anderen Geräten verfügbar ist, ohne die Telefonnummer erneut eingeben oder auswählen zu müssen :

Credential credential = new Credential.Builder(phoneNumberString)
        .setAccountType("https://signin.example.com")  // a URL specific to the app
        .setName(displayName)  // optional: a display name if available
        .build();
Auth.CredentialsApi.save(apiClient, credential).setResultCallback(
            new ResultCallback() {
                public void onResult(Result result) {
                    Status status = result.getStatus();
                    if (status.isSuccess()) {
                        Log.d(TAG, "SAVE: OK");  // already saved
                    } else if (status.hasResolution()) {
                        // Prompt the user to save
                        status.startResolutionForResult(this, RC_SAVE);
                    }
                }
            });

Nachdem der Benutzer die App erneut installiert oder die App auf einem neuen Gerät installiert hat, können Sie die gespeicherte Telefonnummer abrufen, ohne den Benutzer erneut nach seiner Telefonnummer fragen zu müssen:

// On the next install, retrieve the phone number
mCredentialRequest = new CredentialRequest.Builder()
    .setAccountTypes("https://signin.example.com")  // the URL specific to the developer
    .build();
Auth.CredentialsApi.request(apiClient, mCredentialRequest).setResultCallback(
    new ResultCallback<CredentialRequestResult>() {
        public void onResult(CredentialRequestResult credentialRequestResult) {
            if (credentialRequestResult.getStatus().isSuccess()) {
                credentialRequestResult.getCredential().getId();  // this is the phone number
            }
        }
    });

// Then, initiate verification and sign the user in (same as original verification logic)