Bir Android Uygulamasında SMS Doğrulaması İsteyin

Telefon numaralarını otomatik olarak doğrulamak için doğrulama akışının hem istemci hem de sunucu kısımlarını uygulamanız gerekir. Bu belge, bir Android uygulamasında istemci bölümünün nasıl uygulanacağını açıklar.

Bir Android uygulamasında telefon numarası doğrulama akışını başlatmak için, telefon numarasını doğrulama sunucunuza gönderir ve uygulamanız için tek seferlik bir kod içeren bir SMS mesajını dinlemeye başlamak için SMS Retriever API'sini ararsınız. Mesajı aldıktan sonra doğrulama işlemini tamamlamak için tek seferlik kodu sunucunuza geri gönderirsiniz.

Sen başlamadan önce

Uygulamanızı hazırlamak için aşağıdaki bölümlerdeki adımları tamamlayın.

Uygulama önkoşulları

Uygulamanızın derleme dosyasının aşağıdaki değerleri kullandığından emin olun:

  • 19 veya daha yüksek bir minSdkVersion
  • 28 veya daha yüksek bir compileSdkVersion

Uygulamanızı yapılandırın

Projeniz düzey build.gradle dosyasında, dahil Google'ın Maven depo ve Maven'in merkezi depo sizin hem de buildscript ve allprojects bölümler:

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

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

Ekle Google Play hizmetleri sizin SMS Retriever API için bağımlılık modülün Gradle yapı dosyası yaygın olduğunu, 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. Kullanıcının telefon numarasını alın

Uygulamanız için uygun olan herhangi bir yolla kullanıcının telefon numarasını alabilirsiniz. Genellikle, kullanıcıdan cihazda kayıtlı telefon numaralarından seçim yapmasını istemek için ipucu seçiciyi kullanmak ve böylece manuel olarak bir telefon numarası girmek zorunda kalmamak en iyi kullanıcı deneyimidir. İpucu seçiciyi kullanmak için:

// 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 alıcısını başlatın

Eğer kullanıcının telefon numarasını doğrulamak için hazır olduğunuzda, bir örneğini almak SmsRetrieverClient , nesnenin çağrı startSmsRetriever ve SMS alma göreve başarı ve başarısızlık dinleyicileri ekleyin:

// 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 alma görevi, uygulamanızı tanımlayan benzersiz bir dize içeren bir SMS mesajını beş dakikaya kadar dinler.

3. Telefon numarasını sunucunuza gönderin

Kullanıcının telefon numarasını aldıktan ve SMS mesajlarını dinlemeye başladıktan sonra, herhangi bir yöntemle (genellikle bir HTTPS POST isteği ile) kullanıcının telefon numarasını doğrulama sunucunuza gönderin.

Sunucunuz bir doğrulama mesajı oluşturur ve belirttiğiniz telefon numarasına SMS ile gönderir. Bkz Server SMS Onayı gerçekleştirin .

4. Doğrulama mesajları alın

Bir doğrulama mesajı kullanıcının cihazına alındığında, Play hizmetleri açıkça uygulamanıza bir yayın yapan SmsRetriever.SMS_RETRIEVED_ACTION mesajının metnini içeren Niyet,. Bir kullan BroadcastReceiver bu doğrulama iletisi için.

In BroadcastReceiver 'ın onReceive işleyicisi, Niyet en ekstralar gelen doğrulama mesajının metnini almak:

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

Bu Kayıt BroadcastReceiver niyet filtreli com.google.android.gms.auth.api.phone.SMS_RETRIEVED (değeri SmsRetriever.SMS_RETRIEVED_ACTION sabiti) ve izin com.google.android.gms.auth.api.phone.permission.SEND (değeri SmsRetriever.SEND_PERMISSION uygulamanızın içinde sabiti) AndroidManifest.xml aşağıdaki örnekte olduğu gibi dosyasının, veya dinamik olarak kullanarak 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. Doğrulama mesajındaki tek seferlik kodu sunucunuza gönderin

Artık doğrulama mesajının metnine sahip olduğunuza göre, mesajdan tek seferlik kodu almak için normal bir ifade veya başka bir mantık kullanın. Tek seferlik kodun biçimi, bunları sunucunuzda nasıl uyguladığınıza bağlıdır.

Son olarak, tek seferlik kodu güvenli bir bağlantı üzerinden sunucunuza gönderin. Sunucunuz tek seferlik kodu aldığında, telefon numarasının doğrulandığını kaydeder.

İsteğe bağlı: Telefon numarasını Parolalar için Smart Lock ile kaydedin

İsteğe bağlı olarak, kullanıcı telefon numarasını doğruladıktan sonra, kullanıcıdan bu telefon numarası hesabını Parolalar için Akıllı Kilit ile kaydetmesini isteyebilirsiniz, böylece telefon numarasını tekrar yazmak veya seçmek zorunda kalmadan diğer uygulamalarda ve diğer cihazlarda otomatik olarak kullanılabilir. :

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

Ardından, kullanıcı uygulamayı yeniden yükledikten veya uygulamayı yeni bir cihaza yükledikten sonra, kullanıcıya tekrar telefon numarasını sormadan kayıtlı telefon numarasını alabilirsiniz:

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