Przesyłanie prośby o weryfikację SMS-a w aplikacji na Androida

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Aby umożliwić automatyczną weryfikację numerów telefonów, musisz wdrożyć w procesie weryfikacji zarówno klienta, jak i serwera. W tym dokumencie opisujemy, jak wdrożyć część klienta w aplikacji na Androida.

Aby rozpocząć proces weryfikacji numeru telefonu w aplikacji na Androida, wyślij numer telefonu na serwer weryfikacji i wywołaj interfejs SMS Fetcher API, aby rozpocząć słuchanie SMS-a z kodem aplikacji. Gdy otrzymasz wiadomość, odbierzesz jednorazowy kod do serwera i dokończysz proces weryfikacji.

Zanim zaczniesz

Aby przygotować aplikację, wykonaj czynności opisane w kolejnych sekcjach.

Wymagania wstępne aplikacji

Upewnij się, że plik kompilacji aplikacji korzysta z tych wartości:

  • MinSdkVersion w wersji 19 lub nowszej
  • Wersja kompilacji: 28 lub nowsza

Konfigurowanie aplikacji

W pliku build.gradle na poziomie projektu uwzględnij repozytorium Maven i centralne repozytorium Maven w sekcjach buildscript i allprojects:

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

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

Dodaj zależność z Usługami Google Play dla interfejsu SMS Fetcher API do pliku kompilacji Gradle, który jest zwykle app/build.gradle:

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

1. Uzyskiwanie numeru telefonu użytkownika

Numer telefonu użytkownika możesz pobrać w sposób odpowiedni dla swojej aplikacji. Często najlepszym rozwiązaniem jest używanie selektora podpowiedzi, który pomaga użytkownikowi wybrać numer telefonu zapisany na urządzeniu. Dzięki temu nie trzeba ręcznie wpisywać numeru telefonu. Aby użyć selektora podpowiedzi:

// 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. Uruchamianie modułu pobierania SMS-ów

Gdy przygotujesz się do weryfikacji numeru telefonu użytkownika, otrzymasz wystąpienie obiektu SmsRetrieverClient, wywołasz funkcję startSmsRetriever i dołączysz odbiorniki powodzenia i niepowodzeń podczas pobierania SMS-ów:

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

Zadanie pobierania SMS-a będzie przez maksymalnie 5 minut czekać na SMS-a, który zawiera unikalny ciąg identyfikujący aplikację.

3. Wyślij numer telefonu na swój serwer

Gdy zdobędziesz numer telefonu użytkownika i zaczniesz nasłuchiwać SMS-ów, wyślij numer telefonu użytkownika na serwer weryfikacji przy użyciu dowolnej metody (zwykle w przypadku żądania HTTPS POST).

Serwer generuje wiadomość weryfikacyjną i wysyła ją SMS-em na podany numer telefonu. Zobacz Przeprowadzanie weryfikacji SMS-em na serwerze.

4. Otrzymuj wiadomości weryfikacyjne

Gdy na urządzeniu użytkownika pojawi się wiadomość weryfikacyjna, Usługi Google Play {0}przekazują do aplikacji intencję SmsRetriever.SMS_RETRIEVED_ACTION, która zawiera tekst wiadomości. Użyj BroadcastReceiver, aby otrzymać tę wiadomość weryfikacyjną.

W obszarze BroadcastReceiver&<39;s onReceive pobierz tekst wiadomości z intencji:

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

Zarejestruj ten BroadcastReceiver w filtrze intencji com.google.android.gms.auth.api.phone.SMS_RETRIEVED (wartość stałej SmsRetriever.SMS_RETRIEVED_ACTION) i uprawnieniu com.google.android.gms.auth.api.phone.permission.SEND (wartość stałej SmsRetriever.SEND_PERMISSION) w pliku AndroidManifest.xml w aplikacji, jak w poniższym przykładzie lub dynamicznie za pomocą 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. Wyślij jednorazowy kod z wiadomości weryfikacyjnej na swój serwer

Masz już treść wiadomości weryfikacyjnej, użyj wyrażenia regularnego lub innej logiki, aby uzyskać jednorazowy kod z wiadomości. Format kodu jednorazowego zależy od tego, jak został zaimplementowany na serwerze.

Na koniec wyślij jednorazowy kod na swój serwer przez zabezpieczone połączenie. Kiedy serwer odbiera kod jednorazowy, rejestruje, że numer telefonu został zweryfikowany.

Opcjonalnie: zapisywanie numeru telefonu za pomocą funkcji Smart Lock na hasła

Opcjonalnie, gdy użytkownik zweryfikuje swój numer telefonu, możesz poprosić go o zapisanie konta telefonu z funkcją Smart Lock na hasła, dzięki czemu będzie ono automatycznie dostępne w innych aplikacjach i na innych urządzeniach bez konieczności wpisywania ani wybierania numeru.

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

Gdy użytkownik ponownie zainstaluje aplikację lub zainstaluje ją na nowym urządzeniu, możesz pobrać zapisany numer telefonu bez konieczności ponownego podawania numeru telefonu przez użytkownika:

// 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)