Sunucu tarafı doğrulama (SSV) geri çağırmalarını doğrulama

Sunucu tarafı doğrulama geri çağırmaları, sorgu parametreleri Google tarafından genişletilen ve Google tarafından harici bir sisteme gönderilen ve kullanıcının ödüllü veya ödüllü geçiş reklamıyla etkileşim kurduğu için kullanıcının ödüllendirilmesi gerektiğini bildirmek için gönderilen URL istekleridir. Ödüllü SSV (sunucu tarafı doğrulaması) geri çağırmaları, kullanıcıları ödüllendirmek için istemci tarafı geri çağırma adres sahteciliğine karşı ek bir koruma katmanı sağlar.

Bu kılavuzda, geri çağırmadaki sorgu parametrelerinin geçerli değerler olduğundan emin olmak için Tink Java Uygulamaları üçüncü taraf kriptografi kitaplığını kullanarak ödüllü SSV geri çağırmalarının nasıl doğrulanacağı gösterilmektedir. Tink bu kılavuzun amaçları doğrultusunda kullanılmış olsa da ECDSA'yı destekleyen herhangi bir üçüncü taraf kitaplığı kullanabilirsiniz. Sunucunuzu, AdMob kullanıcı arayüzündeki test aracıyla da test edebilirsiniz.

Java bahar önyüklemesi kullanan bu tam olarak çalışan örneğe göz atın.

Ön koşullar

Tink Java Uygulamaları kitaplığından RewardedAdsVerifier'ı kullanın

Tink Java Uygulamaları GitHub deposu, ödüllü SSV geri çağırmasını doğrulamak için gereken kodu azaltmak amacıyla bir RewardedAdsVerifier yardımcı sınıfı içerir. Bu sınıfı kullanmak, bir geri çağırma URL'sini aşağıdaki kodla doğrulayabilmenizi sağlar.

RewardedAdsVerifier verifier = new RewardedAdsVerifier.Builder()
    .fetchVerifyingPublicKeysWith(
        RewardedAdsVerifier.KEYS_DOWNLOADER_INSTANCE_PROD)
    .build();
String rewardUrl = ...;
verifier.verify(rewardUrl);

verify() yöntemi istisna oluşturmadan yürütülürse geri çağırma URL'si başarıyla doğrulanmıştır. Kullanıcıyı ödüllendirme bölümünde, kullanıcıların ne zaman ödüllendirilmesi gerektiğiyle ilgili en iyi uygulamalar açıklanır. Ödüllü SSV geri aramalarını doğrulamak amacıyla bu sınıf tarafından gerçekleştirilen adımların dökümünü Ödüllü SSV için manuel doğrulama bölümünden inceleyebilirsiniz.

SSV geri çağırma parametreleri

Sunucu tarafı doğrulama geri çağırmaları, ödüllü reklam etkileşimini açıklayan sorgu parametreleri içerir. Parametre adları, açıklamaları ve örnek değerleri aşağıda listelenmiştir. Parametreler alfabetik sırayla gönderilir.

Parametre Adı Açıklama Örnek değer
ad_network Bu reklamı karşılayan reklam kaynağının reklam kaynağı tanımlayıcısı. Kimlik değerlerine karşılık gelen reklam kaynağı adları, Reklam kaynağı tanımlayıcıları bölümünde listelenir. 1953547073528090325
ad_unit Ödüllü reklam istemek için kullanılan AdMob reklam birimi kimliği. 2747237135
custom_data Sağladığı özel veri dizesi: setCustomData .

Uygulama tarafından herhangi bir özel veri dizesi sağlanmazsa bu sorgu parametresi değeri SSV geri çağırmasında bulunmaz.

SAMPLE_CUSTOM_DATA_STRING
key_id SSV geri aramasını doğrulamak için kullanılacak anahtar. Bu değer, AdMob anahtar sunucusu tarafından sağlanan bir ortak anahtarla eşlenir. 1234567890
reward_amount Reklam birimi ayarlarında belirtildiği şekilde ödül tutarı. 5
reward_item Reklam birimi ayarlarında belirtildiği şekilde ödül öğesi. paralar
signature AdMob tarafından oluşturulan SSV geri araması için imza. MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY
timestamp Kullanıcının ms cinsinden Dönem zamanı olarak ödüllendirildiği zaman damgası. 1507770365237823
transaction_id AdMob tarafından oluşturulan her ödül hibesi etkinliği için benzersiz on altılı tanımlayıcı. 18fa792de1bca816048293fc71035638
user_id setUserId tarafından sağlanan kullanıcı tanımlayıcısı.

Uygulama tarafından herhangi bir kullanıcı tanımlayıcısı sağlanmazsa bu sorgu parametresi SSV geri çağırmasında yer almaz.

1234567

Reklam kaynağı tanımlayıcıları

Reklam kaynağı adları ve kimlikleri

Reklam kaynağı adı Reklam kaynağı kimliği
Aarki (teklifli sistem)5240798063227064260
Reklam Oluşturma (teklifli sistem)1477265452970951479
AdColony15586990674969969776
AdColony (SDK dışı) (teklifli sistem)4600416542059544716
AdColony (teklifli sistem)6895345910719072481
AdFalcon3528208921554210682
AdMob Ağı5450213213286189855
ADResult10593873382626181482
AMoAd17253994435944008978
Aplovin1063618907739174004
Applovin (teklifli sistem)1328079684332308356
Grafik Artırma2873236629771172317
Çikolata Platformu (teklifli sistem)6432849193975106527
Çapraz Kanal (MdotM)9372067028804390441
Özel Etkinlik18351550913290782395
DT Exchange*
* 21 Eylül 2022'den önce bu ağın adı "Fyber Marketplace"ti.
2179455223494392917
EMX (teklifli sistem)8497809869790333482
Değişken (teklifli sistem)8419777862490735710
Hafif kar yağışı3376427960656545613
Fyber*
* Bu reklam kaynağı, geçmiş raporlaması için kullanılmaktadır.
4839637394546996422
i-mobile5208827440166355534
Enhanced Digital (teklifli sistem)159382223051638006
Dizin Değişimi (teklifli sistem)4100650709078789802
InMobi7681903010231960328
InMobi (teklifli sistem)6325663098072678541
IronSource6925240245545091930
Leadbolt2899150749497968595
LG U+REKLAM18298738678491729107
LINE Reklam Ağı3025503711505004547
Maio7505118203095108657
maio (teklifli sistem)1343336733822567166
Media.net (teklifli sistem)2127936450554446159
Uyumlulaştırılmış kurum reklamları6060308706800320801
Meta Audience Network*
* 6 Haziran 2022'den önce bu ağın adı "Facebook Audience Network"tü.
10568273599589928883
Meta Audience Network (teklifli sistem)*
* 6 Haziran 2022'den önce bu ağın adı "Facebook Audience Network (teklifli sistem)" olarak değiştirildi.
11198165126854996598
Mintegral1357746574408896200
Mintegral (teklifli sistem)6250601289653372374
MobFox8079529624516381459
MobFox (teklifli sistem)3086513548163922365
MoPub (kullanımdan kaldırıldı)10872986198578383917
myTarget8450873672465271579
Nend9383070032774777750
AOL'den ONE (Millennial Media)6101072188699264581
AOL'den ONE (Nexage)3224789793037044399
OneTag Exchange (teklifli sistem)4873891452523427499
OpenX (teklifli sistem)4918705482605678398
Pangle (teklifli sistem)3525379893916449117
PubMatic (teklifli sistem)3841544486172445473
Rezervasyon kampanyası7068401028668408324
RhythmOne (teklifli sistem)2831998725945605450
Rubicon (teklifli sistem)3993193775968767067
SK gezegeni734341340207269415
Paylaşım (teklifli sistem)5247944089976324188
Smaato (teklifli sistem)3362360112145450544
Equativ (teklifli sistem)*

* 12 Ocak 2023'ten önce bu ağa "Akıllı Reklam Sunucusu" adı veriliyordu.

5970199210771591442
Sonobi (teklifli sistem)3270984106996027150
Tapjoy7295217276740746030
Tapjoy (teklifli sistem)4692500501762622178
Tencent GDT7007906637038700218
TripleLift (teklifli sistem)8332676245392738510
Unity Reklamları4970775877303683148
UnrulyX (teklifli sistem)2831998725945605450
Verizon Media7360851262951344112
Verve Grubu (teklifli sistem)5013176581647059185
VPN1940957084538325905
Artış Para Kazanma*

* 30 Ocak 2023'ten önce bu ağa "Vungle" adı veriliyordu.

1953547073528090325
Liftoff Para Kazanma (teklifli sistem)*

* 30 Ocak 2023'ten önce bu ağın adı "Vungle (teklifli sistem)" olarak geçiyordu.

4692500501762622185
Yieldmo (teklifli sistem)4193081836471107579
YieldOne (teklifli sistem)3154533971590234104
Zucks5506531810221735863

Kullanıcıyı ödüllendirme

Kullanıcıyı ne zaman ödüllendireceğinize karar verirken kullanıcı deneyimi ile doğrulamayı dengelemek önemlidir. Sunucu tarafı geri çağırma işlemleri, harici sistemlere ulaşmadan önce gecikmeler yaşayabilir. Bu nedenle, önerilen en iyi uygulama, sunucu tarafı geri çağırmalar alındığında tüm ödüller için doğrulama gerçekleştirirken kullanıcıyı hemen ödüllendirmek için istemci taraflı geri çağırmanın kullanılmasıdır. Bu yaklaşım, verilen ödüllerin geçerliliğini sağlarken iyi bir kullanıcı deneyimi sağlar.

Bununla birlikte, ödül geçerliliğinin kritik olduğu (örneğin, ödül, uygulamanızın oyun içi ekonomisini etkileyen) ve ödül vermede gecikmelerin kabul edilebilir olduğu uygulamalar için doğrulanmış sunucu tarafının geri aranmasını beklemek en iyi yaklaşım olabilir.

Özel veriler

Sunucu tarafı doğrulama geri çağırmalarında ek veri gerektiren uygulamalar, ödüllü reklamların özel veri özelliğini kullanmalıdır. Ödüllü reklam nesnesinde ayarlanan herhangi bir dize değeri, SSV geri çağırmasının custom_data sorgu parametresine iletilir. Herhangi bir özel veri değeri ayarlanmazsa custom_data sorgu parametresi değeri SSV geri çağırmasında yer almaz.

Aşağıdaki kod örneğinde, ödüllü reklam yüklendikten sonra SSV seçeneklerinin nasıl ayarlanacağı gösterilmektedir.

Java

RewardedAd.load(MainActivity.this, "ca-app-pub-3940256099942544/5354046379",
    new AdRequest.Builder().build(),  new RewardedAdLoadCallback() {
  @Override
  public void onAdLoaded(RewardedAd ad) {
    Log.d(TAG, "Ad was loaded.");
    rewardedAd = ad;
    ServerSideVerificationOptions options = new ServerSideVerificationOptions
        .Builder()
        .setCustomData("SAMPLE_CUSTOM_DATA_STRING")
        .build();
    rewardedAd.setServerSideVerificationOptions(options);
  }
  @Override
  public void onAdFailedToLoad(LoadAdError loadAdError) {
    Log.d(TAG, loadAdError.toString());
    rewardedAd = null;
  }
});

Kotlin

RewardedAd.load(this, "ca-app-pub-3940256099942544/5354046379",
    AdRequest.Builder().build(), object : RewardedAdLoadCallback() {
  override fun onAdLoaded(ad: RewardedAd) {
    Log.d(TAG, "Ad was loaded.")
    rewardedInterstitialAd = ad
    val options = ServerSideVerificationOptions.Builder()
        .setCustomData("SAMPLE_CUSTOM_DATA_STRING")
        .build()
    rewardedAd.setServerSideVerificationOptions(options)
  }

  override fun onAdFailedToLoad(adError: LoadAdError) {
    Log.d(TAG, adError?.toString())
    rewardedAd = null
  }
})

Özel ödül dizesini ayarlamak istiyorsanız bunu reklamı göstermeden önce yapmanız gerekir.

Ödüllü SSV'nin manuel doğrulaması

Ödüllü SSV'yi doğrulamak için RewardedAdsVerifier sınıfı tarafından gerçekleştirilen adımlar aşağıda özetlenmiştir. Dahil edilen kod snippet'leri Java'da olsa ve Tink üçüncü taraf kitaplığından yararlansa da bu adımları ECDSA'yı destekleyen herhangi bir üçüncü taraf kitaplığı kullanarak istediğiniz dilde uygulayabilirsiniz.

Ortak anahtarları getir

Ödüllü SSV geri çağırmasını doğrulamak için AdMob tarafından sağlanan bir ortak anahtara ihtiyacınız vardır.

Ödüllü SSV geri çağırmalarını doğrulamak için kullanılacak genel anahtarların listesi, AdMob anahtar sunucusundan alınabilir. Ortak anahtarların listesi, aşağıdakine benzer bir biçimde JSON gösterimi olarak sağlanır:

{
 "keys": [
    {
      keyId: 1916455855,
      pem: "-----BEGIN PUBLIC KEY-----\nMF...YTPcw==\n-----END PUBLIC KEY-----"
      base64: "MFkwEwYHKoZIzj0CAQYI...ltS4nzc9yjmhgVQOlmSS6unqvN9t8sqajRTPcw=="
    },
    {
      keyId: 3901585526,
      pem: "-----BEGIN PUBLIC KEY-----\nMF...aDUsw==\n-----END PUBLIC KEY-----"
      base64: "MFYwEAYHKoZIzj0CAQYF...4akdWbWDCUrMMGIV27/3/e7UuKSEonjGvaDUsw=="
    },
  ],
}

Ortak anahtarları almak için AdMob anahtar sunucusuna bağlanın ve anahtarları indirin. Aşağıdaki kod bu görevi tamamlar ve anahtarların JSON gösterimini data değişkenine kaydeder.

String url = ...;
NetHttpTransport httpTransport = new NetHttpTransport.Builder().build();
HttpRequest httpRequest =
    httpTransport.createRequestFactory().buildGetRequest(new GenericUrl(url));
HttpResponse httpResponse = httpRequest.execute();
if (httpResponse.getStatusCode() != HttpStatusCodes.STATUS_CODE_OK) {
  throw new IOException("Unexpected status code = " + httpResponse.getStatusCode());
}
String data;
InputStream contentStream = httpResponse.getContent();
try {
  InputStreamReader reader = new InputStreamReader(contentStream, UTF_8);
  data = readerToString(reader);
} finally {
  contentStream.close();
}

Ortak anahtarların düzenli olarak döndürüldüğünü unutmayın. Rotasyon tarihi belli olan bir e-posta alacaksınız. Ortak anahtarları önbelleğe alıyorsanız bu e-postayı aldıktan sonra anahtarları güncellemeniz gerekir.

Ortak anahtarlar getirildikten sonra ayrıştırılmaları gerekir. Aşağıdaki parsePublicKeysJson yöntemi, yukarıdaki örnekte olduğu gibi bir JSON dizesini giriş olarak alır ve key_id değerlerinden ortak anahtarlara eşleme oluşturur. Bunlar Tink kitaplığından ECPublicKey nesneleri olarak kapsüllenir.

private static Map<Integer, ECPublicKey> parsePublicKeysJson(String publicKeysJson)
    throws GeneralSecurityException {
  Map<Integer, ECPublicKey> publicKeys = new HashMap<>();
  try {
    JSONArray keys = new JSONObject(publicKeysJson).getJSONArray("keys");
    for (int i = 0; i < keys.length(); i++) {
      JSONObject key = keys.getJSONObject(i);
      publicKeys.put(
          key.getInt("keyId"),
          EllipticCurves.getEcPublicKey(Base64.decode(key.getString("base64"))));
    }
  } catch (JSONException e) {
    throw new GeneralSecurityException("failed to extract trusted signing public keys", e);
  }
  if (publicKeys.isEmpty()) {
    throw new GeneralSecurityException("No trusted keys are available.");
  }
  return publicKeys;
}

İçeriğin doğrulanmasını sağlayın

Ödüllü SSV geri çağırmalarının son iki sorgu parametresi her zaman bu sırayla signature ve key_id, olur. Kalan sorgu parametreleri doğrulanacak içeriği belirtir. AdMob'u https://www.myserver.com/mypath adresine ödül geri çağırmaları gönderecek şekilde yapılandırdığınızı varsayalım. Aşağıdaki snippet'te, doğrulanacak içeriğin vurgulandığı bir ödüllü SSV geri çağırma örneği gösterilmektedir.

https://www.myserver.com/path?ad_network=54...55&ad_unit=12345678&reward_amount=10&reward_item=coins
&timestamp=150777823&transaction_id=12...DEF&user_id=1234567&signature=ME...Z1c&key_id=1268887

Aşağıdaki kod, geri çağırma URL'sinden UTF-8 bayt dizisi olarak doğrulanacak içeriğin nasıl ayrıştırılacağını gösterir.

public static final String SIGNATURE_PARAM_NAME = "signature=";
...
URI uri;
try {
  uri = new URI(rewardUrl);
} catch (URISyntaxException ex) {
  throw new GeneralSecurityException(ex);
}
String queryString = uri.getQuery();
int i = queryString.indexOf(SIGNATURE_PARAM_NAME);
if (i == -1) {
  throw new GeneralSecurityException("needs a signature query parameter");
}
byte[] queryParamContentData =
    queryString
        .substring(0, i - 1)
        // i - 1 instead of i because of & in the query string
        .getBytes(Charset.forName("UTF-8"));

Geri çağırma URL'sinden imza ve key_id değerini alma

Önceki adımda yer alan queryString değerini kullanarak, geri çağırma URL'sindeki signature ve key_id sorgu parametrelerini aşağıda gösterildiği gibi ayrıştırın:

public static final String KEY_ID_PARAM_NAME = "key_id=";
...
String sigAndKeyId = queryString.substring(i);
i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME);
if (i == -1) {
  throw new GeneralSecurityException("needs a key_id query parameter");
}
String sig =
    sigAndKeyId.substring(
        SIGNATURE_PARAM_NAME.length(), i - 1 /* i - 1 instead of i because of & */);
int keyId = Integer.valueOf(sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length()));

Doğrulama gerçekleştirme

Son adım, geri çağırma URL'sinin içeriğini uygun ortak anahtarla doğrulamaktır. parsePublicKeysJson yönteminden döndürülen eşlemeyi alın ve bu eşlemeden ortak anahtarı almak için geri çağırma URL'sindeki key_id parametresini kullanın. Ardından imzayı bu ortak anahtarla doğrulayın. Bu adımlar, aşağıda verify yönteminde gösterilmiştir.

private void verify(final byte[] dataToVerify, int keyId, final byte[] signature)
    throws GeneralSecurityException {
  Map<Integer, ECPublicKey> publicKeys = parsePublicKeysJson();
  if (publicKeys.containsKey(keyId)) {
    foundKeyId = true;
    ECPublicKey publicKey = publicKeys.get(keyId);
    EcdsaVerifyJce verifier = new EcdsaVerifyJce(publicKey, HashType.SHA256, EcdsaEncoding.DER);
    verifier.verify(signature, dataToVerify);
  } else {
    throw new GeneralSecurityException("cannot find verifying key with key ID: " + keyId);
  }
}

Yöntem, istisna bildirilmeden yürütülürse geri çağırma URL'si başarıyla doğrulanmıştır.

SSS

AdMob anahtar sunucusu tarafından sağlanan ortak anahtarı önbelleğe alabilir miyim?
SSV geri aramalarını doğrulamak için gereken işlem sayısını azaltmak amacıyla AdMob anahtar sunucusu tarafından sağlanan ortak anahtarı önbelleğe almanızı öneririz. Bununla birlikte, ortak anahtarların düzenli olarak döndürüldüğünü ve 24 saatten uzun süre önbellekte tutulmaması gerektiğini unutmayın.
AdMob anahtar sunucusu tarafından sağlanan ortak anahtarlar ne sıklıkta döndürülüyor?
AdMob anahtar sunucusu tarafından sağlanan ortak anahtarlar, değişken bir plana göre dönüşümlü olarak yayınlanır. SSV geri aramalarının doğrulanmasının istenen şekilde çalışmaya devam etmesini sağlamak için ortak anahtarlar, 24 saatten uzun süre önbelleğe alınmamalıdır.
Sunucuma erişilemiyorsa ne olur?
Google, SSV geri çağırmaları için HTTP 200 OK başarı durumu yanıt kodu bekler. Sunucunuza ulaşılamazsa veya beklenen yanıtı sağlamazsa Google, SSV geri aramalarını bir saniyelik aralıklarla beş kereye kadar göndermeyi tekrar dener.
SSV geri aramalarının Google'dan geldiğini nasıl doğrulayabilirim?
SSV geri aramalarının Google kaynaklı olduğunu doğrulamak için ters DNS aramasını kullanın.