सर्वर साइड पुष्टि (SSV) कॉलबैक की पुष्टि करें

सर्वर-साइड पर पुष्टि करने वाले कॉलबैक, यूआरएल के अनुरोध होते हैं. Google इन क्वेरी पैरामीटर को बढ़ाता है. ये पैरामीटर Google किसी बाहरी सिस्टम को भेजते हैं. इससे उपयोगकर्ता को पता चलता है कि इनाम वाले या इनाम वाले इंटरस्टीशियल विज्ञापन से इंटरैक्ट करने पर, उपयोगकर्ता को इनाम मिलना चाहिए. इनाम वाले SSV (सर्वर-साइड वेरिफ़िकेशन) कॉलबैक, उपयोगकर्ताओं को इनाम देने के लिए क्लाइंट-साइड कॉलबैक के स्पूफ़िंग (झूठे नाम से मेल भेजना) से सुरक्षा की एक और लेयर उपलब्ध कराते हैं.

इस गाइड में आपको Tink Java ऐप्लिकेशन की तीसरे पक्ष की क्रिप्टोग्राफ़िक लाइब्रेरी का इस्तेमाल करके, इनाम वाले SSV कॉलबैक की पुष्टि करने का तरीका बताया गया है. इससे यह पक्का किया जा सकता है कि कॉलबैक में क्वेरी पैरामीटर मान्य वैल्यू हैं. हालांकि, इस गाइड में शामिल कुछ मामलों में Tink का इस्तेमाल किया गया है, फिर भी आपके पास तीसरे पक्ष की ऐसी किसी भी लाइब्रेरी का इस्तेमाल करने का विकल्प है जो ECDSA की सुविधा देती है. आप AdMob यूज़र इंटरफ़ेस (यूआई) में टेस्टिंग टूल से अपने सर्वर की जांच भी कर सकते हैं.

Java Spring-boot का इस्तेमाल करने वाला पूरी तरह से काम करने वाला उदाहरण देखें.

ज़रूरी शर्तें

Tink Java Apps लाइब्रेरी से RewardedAdsVerifier का इस्तेमाल करें

Tink Java Apps GitHub रिपॉज़िटरी में एक RewardedAdsVerifier हेल्पर क्लास शामिल है, जो इनाम वाले SSV कॉलबैक की पुष्टि करने के लिए ज़रूरी कोड को कम करती है. इस क्लास का इस्तेमाल करके, इस कोड के साथ कॉलबैक यूआरएल की पुष्टि की जा सकती है.

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

अगर verify() वाला तरीका बिना किसी अपवाद के काम करता है, तो कॉलबैक यूआरएल की पुष्टि हो गई है. उपयोगकर्ता को इनाम देना सेक्शन में, उपयोगकर्ताओं को इनाम देने के सबसे सही तरीकों के बारे में बताया गया है. इनाम वाले SSV कॉलबैक की पुष्टि करने के लिए, इस क्लास ने जो तरीके अपनाए हैं उनके बारे में जानने के लिए, इनाम वाले SSV कॉलबैक की मैन्युअल पुष्टि वाले सेक्शन को पढ़ें.

एसएसवी कॉलबैक पैरामीटर

सर्वर-साइड पुष्टि वाले कॉलबैक में क्वेरी पैरामीटर होते हैं, जो इनाम वाले विज्ञापन इंटरैक्शन की जानकारी देते हैं. पैरामीटर के नाम, जानकारी, और उदाहरण की वैल्यू यहां दी गई हैं. पैरामीटर, वर्णमाला के क्रम में भेजे जाते हैं.

पैरामीटर का नाम ब्यौरा उदाहरण के तौर पर दी गई वैल्यू
ad_network उस विज्ञापन स्रोत के लिए विज्ञापन स्रोत आइडेंटिफ़ायर जिसने इस विज्ञापन को पूरा किया है. आईडी की वैल्यू से जुड़े विज्ञापन स्रोत के नाम, विज्ञापन सोर्स आइडेंटिफ़ायर सेक्शन में दिए गए हैं. 1953547073528090325
ad_unit AdMob विज्ञापन यूनिट का आईडी, जिसका इस्तेमाल इनाम वाले विज्ञापन का अनुरोध करने के लिए किया गया था. 2747237135
custom_data customRewardString से मिली कस्टम डेटा स्ट्रिंग.

अगर ऐप्लिकेशन, कस्टम डेटा स्ट्रिंग नहीं देता है, तो क्वेरी पैरामीटर की यह वैल्यू, SSV कॉलबैक में मौजूद नहीं होगी.

SAMPLE_CUSTOM_DATA_STRING
key_id SSV कॉलबैक की पुष्टि करने के लिए इस्तेमाल की जाने वाली कुंजी. यह वैल्यू, AdMob के कुंजी सर्वर से मिली सार्वजनिक कुंजी से मैप होती है. 1234567890
reward_amount विज्ञापन यूनिट की सेटिंग में दी गई इनाम की रकम. 5
reward_item विज्ञापन यूनिट की सेटिंग में बताया गया इनाम आइटम. सिक्के
signature AdMob से जनरेट किए गए SSV कॉलबैक के लिए हस्ताक्षर. MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY
timestamp उस समय का टाइमस्टैंप जब उपयोगकर्ता को मिलीसेकंड में Epoch के समय के तौर पर इनाम दिया गया था. 1507770365237823
transaction_id AdMob से जनरेट किए गए, इनाम के हर इवेंट के लिए, हेक्स कोड में बदला गया यूनीक आइडेंटिफ़ायर. 18fa792de1bca816048293fc71035638
user_id userIdentifier.

अगर ऐप्लिकेशन से कोई उपयोगकर्ता आइडेंटिफ़ायर नहीं मिलता है, तो यह क्वेरी पैरामीटर SSV कॉलबैक में मौजूद नहीं होगा.

1234567

विज्ञापन स्रोत के आइडेंटिफ़ायर

विज्ञापन स्रोत के नाम और आईडी

विज्ञापन स्रोत का नाम विज्ञापन स्रोत आईडी
आर्की (बिडिंग)5240798063227064260
विज्ञापन जनरेशन (बिडिंग)1477265452970951479
AdColony15586990674969969776
AdColony (SDK टूल के अलावा) (बिडिंग)4600416542059544716
AdColony (बिडिंग)6895345910719072481
AdFalcon3528208921554210682
AdMob नेटवर्क5450213213286189855
ADResult10593873382626181482
AMoविज्ञापन17253994435944008978
एप्लोविन1063618907739174004
एप्लोविन (बिडिंग)1328079684332308356
चार्टबूस्ट2873236629771172317
Chocolate Platform (बिडिंग)6432849193975106527
क्रॉसचैनल (MdotM)9372067028804390441
कस्टम इवेंट18351550913290782395
DT Exchange*
* 21 सितंबर, 2022 से पहले, इस नेटवर्क का नाम "Fyber Marketplace" था.
2179455223494392917
ईएमएक्स (बिडिंग)8497809869790333482
उतार-चढ़ाव (बिडिंग)8419777862490735710
हवा के साथ बारिश या बर्फ़ का झोंका3376427960656545613
Fyber*
* इस विज्ञापन स्रोत का इस्तेमाल, पुरानी रिपोर्टिंग के लिए किया जाता है.
4839637394546996422
i-mobile5208827440166355534
डिजिटल कैंपेन के ज़रिए (बिडिंग) को बेहतर बनाएं159382223051638006
इंडेक्स एक्सचेंज (बिडिंग)4100650709078789802
InMobi7681903010231960328
InMobi (बिडिंग)6325663098072678541
IronSource6925240245545091930
Leadbolt2899150749497968595
एलजी यू+एडी18298738678491729107
LINE विज्ञापन नेटवर्क3025503711505004547
Maio7505118203095108657
maio (बिडिंग)1343336733822567166
Media.net (बिडिंग)2127936450554446159
मीडिएशन वाले हाउस विज्ञापन6060308706800320801
Meta Audience Network*
* इस नेटवर्क का नाम 6 जून, 2022 से पहले, "Facebook Audience Network" था.
10568273599589928883
Meta Audience Network (बिडिंग)*
* 6 जून, 2022 से पहले, इस नेटवर्क का नाम "Facebook Audience Network (बिडिंग)" था.
11198165126854996598
मिंटग्रल1357746574408896200
Mintegral (बिडिंग)6250601289653372374
MobFox8079529624516381459
MobFox (बिडिंग)3086513548163922365
MoPub (अब सेवा में नहीं है)10872986198578383917
myTarget8450873672465271579
Nend9383070032774777750
ONE by AOL (मिलेनियल मीडिया)6101072188699264581
ONE by AOL (नेक्सेज)3224789793037044399
OneTag एक्सचेंज (बिडिंग)4873891452523427499
OpenX (बिडिंग)4918705482605678398
Pang (बिडिंग)3525379893916449117
PubMatic (बिडिंग)3841544486172445473
रिज़र्वेशन कैंपेन7068401028668408324
RhythmOne (बिडिंग)2831998725945605450
रूबिकॉन (बिडिंग)3993193775968767067
SK ग्रह734341340207269415
शेयरथ्रू (बिडिंग)5247944089976324188
Smaato (बिडिंग)3362360112145450544
बराबर (बिडिंग)*

* इस नेटवर्क का नाम 12 जनवरी, 2023 से पहले "स्मार्ट एड सर्वर" था.

5970199210771591442
Sonobi (बिडिंग)3270984106996027150
Tapjoy7295217276740746030
टैपजॉय (बिडिंग)4692500501762622178
Tencent GDT7007906637038700218
TripleLift (बिडिंग)8332676245392738510
Unity विज्ञापन4970775877303683148
UnrulyX (बिडिंग)2831998725945605450
Verizon मीडिया7360851262951344112
Verve Group (बिडिंग)5013176581647059185
वीपीएन1940957084538325905
Liftoff Monetize*

* इस नेटवर्क का नाम "Vungle" था. 30 जनवरी, 2023 से पहले, इस नेटवर्क का नाम "Vungle" था.

1953547073528090325
लिफ़्टऑफ़ कमाई (बिडिंग)*

* इस नेटवर्क का नाम 30 जनवरी, 2023 से पहले "Vungle (बिडिंग)" था.

4692500501762622185
Yieldmo (बिडिंग)4193081836471107579
YieldOne (बिडिंग)3154533971590234104
ज़ुक्स5506531810221735863

उपयोगकर्ता को इनाम देना

किसी उपयोगकर्ता को कब इनाम देना है, यह तय करते समय उपयोगकर्ता अनुभव और इनाम की पुष्टि के बीच संतुलन होना ज़रूरी है. बाहरी सिस्टम तक पहुंचने से पहले, सर्वर-साइड कॉलबैक को देर हो सकती है. इसलिए, सबसे सही तरीका यह है कि उपयोगकर्ता को तुरंत इनाम देने के लिए, क्लाइंट-साइड कॉलबैक का इस्तेमाल करें. साथ ही, सर्वर-साइड कॉलबैक मिलने पर सभी इनामों की पुष्टि करें. इस तरीके से, दिए गए इनामों की वैधता पक्का करते हुए अच्छा उपयोगकर्ता अनुभव मिलता है.

हालांकि, जिन ऐप्लिकेशन के लिए इनाम की पुष्टि ज़रूरी है (उदाहरण के लिए, इनाम से आपके ऐप्लिकेशन की इन-गेम इकॉनमी पर असर पड़ता है) और इनाम देने में देरी होना स्वीकार किया जाता है, वहां पुष्टि किए गए सर्वर साइड कॉलबैक का इंतज़ार करना सबसे सही तरीका हो सकता है.

कस्टम डेटा

जिन ऐप्लिकेशन को सर्वर-साइड वेरिफ़िकेशन कॉलबैक में ज़्यादा डेटा की ज़रूरत होती है उन्हें इनाम वाले विज्ञापनों की पसंद के मुताबिक डेटा की सुविधा का इस्तेमाल करना चाहिए. इनाम वाले विज्ञापन ऑब्जेक्ट पर सेट की गई कोई भी स्ट्रिंग वैल्यू, SSV कॉलबैक के custom_data क्वेरी पैरामीटर को पास की जाती है. अगर कोई कस्टम डेटा वैल्यू सेट नहीं की गई है, तो custom_data क्वेरी पैरामीटर की वैल्यू, SSV कॉलबैक में नहीं होगी.

नीचे दिए गए कोड सैंपल में बताया गया है कि इनाम वाले विज्ञापन के लोड होने के बाद, SSV विकल्प कैसे सेट करें.

Swift

GADRewardedAd.load(withAdUnitID:"ca-app-pub-3940256099942544/1712485313",
                       request: request,
                       completionHandler: { [self] ad, error in
      if let error != error {
      rewardedAd = ad
      let options = GADServerSideVerificationOptions()
      options.customRewardString = "SAMPLE_CUSTOM_DATA_STRING"
      rewardedAd.serverSideVerificationOptions = options
    }

Objective-C

GADRequest *request = [GADRequest request];
[GADRewardedAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
                        request:request
              completionHandler:^(GADRewardedAd *ad, NSError *error) {
                if (error) {
                  // Handle Error
                  return;
                }
                self.rewardedAd = ad;
                GADServerSideVerificationOptions *options =
                    [[GADServerSideVerificationOptions alloc] init];
                options.customRewardString = @"SAMPLE_CUSTOM_DATA_STRING";
                ad.serverSideVerificationOptions = options;
              }];

इनाम वाले एसएसवी की मैन्युअल पुष्टि

इनाम वाले एसएसवी की पुष्टि करने के लिए, RewardedAdsVerifier क्लास जो तरीका अपनाती है उसके बारे में नीचे बताया गया है. हालांकि, शामिल किए गए कोड स्निपेट Java में हैं और Tink तीसरे पक्ष की लाइब्रेरी का इस्तेमाल करते हैं, लेकिन इन चरणों को अपनी पसंद की भाषा में लागू किया जा सकता है. ECDSA की सुविधा देने वाली तीसरे पक्ष की किसी भी लाइब्रेरी का इस्तेमाल करके ऐसा किया जा सकता है.

सार्वजनिक कुंजियां फ़ेच करें

इनाम वाले SSV कॉलबैक की पुष्टि करने के लिए, आपको AdMob से मिली सार्वजनिक कुंजी की ज़रूरत होगी.

इनाम वाले SSV कॉलबैक की पुष्टि करने के लिए, इस्तेमाल की जाने वाली सार्वजनिक कुंजियों की सूची को AdMob के कुंजी सर्वर से फ़ेच किया जा सकता है. सार्वजनिक कुंजियों की सूची को JSON फ़ॉर्मैट में दिखाया जाता है. इसका फ़ॉर्मैट यहां दिया गया है:

{
 "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=="
    },
  ],
}

सार्वजनिक कुंजियों को वापस पाने के लिए, AdMob कुंजी के सर्वर से कनेक्ट करें और बटन डाउनलोड करें. नीचे दिया गया कोड, इस टास्क को पूरा करता है और कुंजियों के JSON वैरिएबल को data वैरिएबल में सेव करता है.

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

ध्यान दें कि सार्वजनिक पासकोड समय-समय पर बदलते रहते हैं. होने वाले रोटेशन की जानकारी देने के लिए आपको एक ईमेल मिलेगा. अगर सार्वजनिक कुंजियों को कैश मेमोरी में सेव किया जा रहा है, तो यह ईमेल मिलने पर आपको कुंजियों को अपडेट करना होगा.

सार्वजनिक कुंजियों को फ़ेच करने के बाद, उन्हें पार्स करना ज़रूरी होता है. यहां दिया गया parsePublicKeysJson तरीका एक JSON स्ट्रिंग है, जैसा कि इनपुट के तौर पर ऊपर दिया गया है. साथ ही, यह key_id वैल्यू से सार्वजनिक कुंजियों के लिए मैपिंग बनाता है, जिन्हें Tink लाइब्रेरी के ECPublicKey ऑब्जेक्ट के तौर पर एन्क्रिप्ट (सुरक्षित) किया जाता है.

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

पुष्टि के लिए कॉन्टेंट पाएं

इनाम वाले एसएसवी कॉलबैक के आखिरी दो क्वेरी पैरामीटर हमेशा signature और key_id, इसी क्रम में होते हैं. बाकी क्वेरी पैरामीटर से यह तय होता है कि किस कॉन्टेंट की पुष्टि करनी है. मान लें कि आपने AdMob को इस तरह से कॉन्फ़िगर किया है कि वह https://www.myserver.com/mypath को इनाम के कॉलबैक भेज सके. नीचे दिया गया स्निपेट, इनाम वाले एसएसवी कॉलबैक का उदाहरण दिखाता है. इसमें, पुष्टि किए जाने वाले कॉन्टेंट को हाइलाइट किया गया है.

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

नीचे दिया गया कोड बताता है कि किसी कॉलबैक यूआरएल से पुष्टि किए जाने वाले कॉन्टेंट को, UTF-8 बाइट वाले कलेक्शन के तौर पर कैसे पार्स किया जाए.

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

कॉलबैक यूआरएल से हस्ताक्षर और key_id पाएं

पिछले चरण की queryString वैल्यू का इस्तेमाल करके, कॉलबैक यूआरएल से signature और key_id क्वेरी पैरामीटर को पार्स करें, जैसा कि यहां दिखाया गया है:

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

पुष्टि करें

आखिरी चरण में, सही सार्वजनिक कुंजी से कॉलबैक यूआरएल के कॉन्टेंट की पुष्टि की जाती है. parsePublicKeysJson तरीके से लौटाए गए मैप का इस्तेमाल करें और उस मैपिंग से सार्वजनिक कुंजी पाने के लिए, कॉलबैक यूआरएल से key_id पैरामीटर का इस्तेमाल करें. फिर, उस सार्वजनिक कुंजी से हस्ताक्षर की पुष्टि करें. नीचे verify तरीके में बताया गया है.

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

अगर यह तरीका बिना किसी अपवाद के काम करता है, तो कॉलबैक यूआरएल की पुष्टि हो गई है.

अक्सर पूछे जाने वाले सवाल

क्या AdMob कुंजी सर्वर से मिली सार्वजनिक कुंजी को कैश मेमोरी में सेव किया जा सकता है?
हमारा सुझाव है कि आप AdMob के कुंजी सर्वर से मिलने वाली सार्वजनिक कुंजी को कैश मेमोरी में सेव करें. इससे, SSV कॉलबैक की पुष्टि करने के लिए ज़रूरी कार्रवाइयों की संख्या कम हो जाएगी. हालांकि, ध्यान रखें कि सार्वजनिक कुंजियों को समय-समय पर बदला जाता है और उन्हें 24 घंटे से ज़्यादा समय के लिए कैश मेमोरी में नहीं रखा जाना चाहिए.
AdMob कुंजी सर्वर से मिलने वाली सार्वजनिक कुंजियों को कितनी बार बदला जाता है?
AdMob कुंजी का सर्वर से मिलने वाली सार्वजनिक कुंजियां, वैरिएबल शेड्यूल पर बदल जाती हैं. यह पक्का करने के लिए कि SSV कॉलबैक की पुष्टि पहले की तरह काम करती रहे, सार्वजनिक कुंजियों को 24 घंटे से ज़्यादा समय तक कैश मेमोरी में नहीं रखना चाहिए.
अगर मेरे सर्वर से कनेक्ट न हो पाए, तो क्या होगा?
SSV कॉलबैक के लिए, Google को HTTP 200 OK सफलता की स्थिति वाला रिस्पॉन्स कोड चाहिए. अगर आपके सर्वर तक नहीं पहुंचा जा सकता या वह उम्मीद के मुताबिक रिस्पॉन्स नहीं देता, तो Google एक सेकंड के इंटरवल में ज़्यादा से ज़्यादा पांच बार SSV कॉलबैक भेजने की फिर से कोशिश करेगा.
मैं यह कैसे पुष्टि करूं कि SSV कॉलबैक Google से आ रहे हैं?
रिवर्स डीएनएस लुकअप का इस्तेमाल करके, यह पुष्टि करें कि SSV कॉलबैक Google से आते हैं.