Android Uygulamasında SMS Doğrulaması İsteme

Telefon numaralarını otomatik olarak doğrulamak için doğrulama akışının hem istemci hem de sunucu bölümlerini uygulamanız gerekir. Bu belgede, istemci bölümünün Android uygulamasında nasıl uygulanacağı açıklanmaktadır.

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 kod içeren bir SMS mesajını dinlemeye başlamak üzere SMS Retriever API'yi çağırırsınız. Mesajı aldıktan sonra, doğrulama sürecini tamamlamak için tek seferlik kodu sunucunuza geri gönderirsiniz.

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

Uygulama ön koşulları

Uygulamanızın derleme dosyasında aşağıdaki değerlerin kullanıldığından emin olun:

  • minSdkVersion 19 veya sonraki sürümler
  • 28 veya daha yüksek bir compileSdkVersion

Uygulamanızı yapılandırma

Proje düzeyindeki build.gradle dosyanızda, Google'ın Maven deposunu ve Maven merkezi deposunu hem buildscript hem de allprojects bölümünüze ekleyin:

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

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

SMS Retriever API için Google Play Hizmetleri bağımlılığını modülünüzün Gradle derleme dosyasına ekleyin. Bu dosya genellikle app/build.gradle olur:

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

1. Kullanıcının telefon numarasını alma

Kullanıcının telefon numarasını uygulamanız için uygun olan herhangi bir şekilde alabilirsiniz. Genellikle, kullanıcıya cihazda depolanan telefon numaraları arasından seçim yapmasını istemek için ipucu seçiciyi kullanmak ve böylece telefon numarasını manuel olarak yazmak 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ıyı başlatma

Kullanıcının telefon numarasını doğrulamaya hazır olduğunuzda SmsRetrieverClient nesnesinin bir örneğini alın, startSmsRetriever işlevini çağırın ve SMS alma görevine başarı ve hata işleyicileri 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 SMS mesajını beş dakikaya kadar dinler.

3. Telefon numarasını sunucunuza gönderme

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

Sunucunuz bir doğrulama mesajı oluşturur ve bunu belirttiğiniz telefon numarasına SMS olarak gönderir. Sunucuda SMS Doğrulaması Yapma başlıklı makaleyi inceleyin.

4. Doğrulama mesajları alma

Kullanıcının cihazına bir doğrulama mesajı alındığında Play Hizmetleri, mesajın metnini içeren bir SmsRetriever.SMS_RETRIEVED_ACTION Intent'i uygulamanıza açıkça yayınlar. Bu doğrulama mesajını almak için BroadcastReceiver kullanın.

BroadcastReceiver işleyicisinde, doğrulama mesajının metnini (ve isteğe bağlı olarak gönderen adresini) Intent'in ekstralarından alın:onReceive

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

Bu BroadcastReceiver öğesini, aşağıdaki örnekte gösterildiği gibi uygulamanızın AndroidManifest.xml dosyasında niyet filtresi com.google.android.gms.auth.api.phone.SMS_RETRIEVED (SmsRetriever.SMS_RETRIEVED_ACTION sabitinin değeri) ve izin com.google.android.gms.auth.api.phone.permission.SEND (SmsRetriever.SEND_PERMISSION sabitinin değeri) ile kaydedin veya Context.registerReceiver kullanarak dinamik olarak kaydedin.

<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.

Doğrulama mesajının metnini aldığınıza göre, mesajdaki tek kullanımlık kodu almak için normal ifade veya başka bir mantık kullanın. Tek kullanımlık kodların 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.