Callbacks für die serverseitige Überprüfung sind URL-Anfragen mit Suchparametern die von Google an ein externes System gesendet werden, darüber informieren, dass ein Nutzer für die Interaktion mit einer Interstitial-Anzeige mit Prämie. Callbacks für die serverseitige Überprüfung von Anzeigen mit Prämie bieten zusätzlichen Schutz vor Spoofing clientseitiger Callbacks. um Nutzer zu belohnen.
In diesem Leitfaden erfahren Sie, wie Sie Callbacks für die serverseitige Überprüfung von Anzeigen mit Prämie mithilfe der Methode Tink Java Apps (Drittanbieter) Kryptografiebibliothek verwenden, um sicherzustellen, dass die Abfrageparameter im Callback korrekt sind. und legitime Werte. Obwohl Tink für die Zwecke dieses Leitfadens verwendet wird, können Sie Sie können eine beliebige Bibliothek von Drittanbietern verwenden, die ECDSA: Sie können Ihren Server auch mit der Testfunktion auf der AdMob-Benutzeroberfläche.
Sehen Sie sich diese voll funktionsfähige Beispiel mit dem Java-Spring-Boot.
Vorbereitung
Anzeigen mit Prämie in Ihre mobile App mit Version 11.6.0 oder höher des Google Mobile Ads SDK.
Serverseitige Anzeigen mit Prämie aktivieren für den Anzeigenblock.
„RewardAdsVerifier“ aus der Bibliothek für Tink-Java-Apps verwenden
GitHub-Repository für Tink Java Apps
enthält ein
RewardedAdsVerifier
Hilfsklasse verwenden, um den Code zu reduzieren, der zur Bestätigung eines SSV-Rückrufs für Anzeigen mit Prämie erforderlich ist.
Mit dieser Klasse können Sie eine Callback-URL mit dem folgenden Code verifizieren.
RewardedAdsVerifier verifier = new RewardedAdsVerifier.Builder()
.fetchVerifyingPublicKeysWith(
RewardedAdsVerifier.KEYS_DOWNLOADER_INSTANCE_PROD)
.build();
String rewardUrl = ...;
verifier.verify(rewardUrl);
Wenn die Methode verify()
ohne Ausnahme ausgeführt wird,
Die URL wurde bestätigt. Die Option Belohnen für den Nutzer
finden Sie Best Practices dazu, wann Nutzer Prämien erhalten sollten. Für eine
Aufschlüsselung der Schritte, die in diesem Kurs ausgeführt wurden, um SSV-Rückrufe mit Prämie zu bestätigen
Weitere Informationen zur manuellen Bestätigung
SSV.
SSV-Callback-Parameter
Callbacks für die serverseitige Überprüfung enthalten Suchparameter, die die Interaktion mit einer Anzeige mit Prämie. Parameternamen, Beschreibungen und Beispielwerte (siehe unten). Parameter werden in alphabetischer Reihenfolge gesendet.
Parametername | Beschreibung | Beispielwert |
---|---|---|
ad_network | Die Kennung der Anzeigenquelle, von der die Anzeige ausgeliefert wurde. Anzeigenquelle werden die Namen, die ID-Werten entsprechen, in der Spalte Ad Quellenkennzeichnungen. | 1953547073528090325 |
ad_unit | Die ID des AdMob-Anzeigenblocks, der für die Anfrage der Anzeige mit Prämie verwendet wurde. | 2747237135 |
custom_data | Benutzerdefinierter Datenstring wie bereitgestellt von
<ph type="x-smartling-placeholder"></ph>
setCustomData
Wenn von der App kein benutzerdefinierter Datenstring bereitgestellt wird, wird dieser Suchparameter ist im SSV-Callback nicht vorhanden. |
SAMPLE_CUSTOM_DATA_STRING |
key_id | Schlüssel, der zur Überprüfung des SSV-Rückrufs verwendet wird. Dieser Wert ist einem öffentlichen Schlüssel zugeordnet die vom AdMob-Schlüsselserver bereitgestellt werden. | 1234567890 |
reward_amount | Prämienbetrag, der in den Einstellungen für den Anzeigenblock angegeben ist. | 5 |
reward_item | Prämienartikel entsprechend der Angabe in den Anzeigenblockeinstellungen. | Münzen |
Signatur | Signatur für den SSV-Callback, der von AdMob generiert wurde. | MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY |
timestamp | Zeitstempel für den Zeitpunkt, zu dem der Nutzer eine Prämie erhalten hat, als Epochenzeit in ms. | 1507770365237823 |
transaction_id | Eindeutige hexadezimal-codierte Kennung für jedes von AdMob generierte Prämiengewährungsereignis. | 18fa792de1bca816048293fc71035638 |
user_id | Nutzer-ID wie bereitgestellt von
setUserId
Wenn die App keine Nutzerkennung bereitstellt, wird dieser Suchparameter im SSV-Callback vorhanden sein müssen. |
1234567 |
IDs der Anzeigenquellen
Namen und IDs von Anzeigenquellen
Ad source name | Ad source ID |
---|---|
Aarki (bidding) | 5240798063227064260 |
Ad Generation (bidding) | 1477265452970951479 |
AdColony | 15586990674969969776 |
AdColony (non-SDK) (bidding) | 4600416542059544716 |
AdColony (bidding) | 6895345910719072481 |
AdFalcon | 3528208921554210682 |
AdMob Network | 5450213213286189855 |
AdMob Network Waterfall | 1215381445328257950 |
ADResult | 10593873382626181482 |
AMoAd | 17253994435944008978 |
Applovin | 1063618907739174004 |
Applovin (bidding) | 1328079684332308356 |
Chartboost | 2873236629771172317 |
Chocolate Platform (bidding) | 6432849193975106527 |
CrossChannel (MdotM) | 9372067028804390441 |
Custom Event | 18351550913290782395 |
DT Exchange* * Prior to September 21, 2022, this network was called "Fyber Marketplace". | 2179455223494392917 |
EMX (bidding) | 8497809869790333482 |
Fluct (bidding) | 8419777862490735710 |
Flurry | 3376427960656545613 |
Fyber* * This ad source is used for historical reporting. | 4839637394546996422 |
i-mobile | 5208827440166355534 |
Improve Digital (bidding) | 159382223051638006 |
Index Exchange (bidding) | 4100650709078789802 |
InMobi | 7681903010231960328 |
InMobi (bidding) | 6325663098072678541 |
InMobi Exchange (bidding) | 5264320421916134407 |
IronSource | 6925240245545091930 |
ironSource Ads (bidding) | 1643326773739866623 |
Leadbolt | 2899150749497968595 |
LG U+AD | 18298738678491729107 |
LINE Ads Network | 3025503711505004547 |
maio | 7505118203095108657 |
maio (bidding) | 1343336733822567166 |
Media.net (bidding) | 2127936450554446159 |
Mediated house ads | 6060308706800320801 |
Meta Audience Network* * Prior to June 6, 2022, this network was called "Facebook Audience Network". | 10568273599589928883 |
Meta Audience Network (bidding)* * Prior to June 6, 2022, this network was called "Facebook Audience Network (bidding)". | 11198165126854996598 |
Mintegral | 1357746574408896200 |
Mintegral (bidding) | 6250601289653372374 |
MobFox | 8079529624516381459 |
MobFox (bidding) | 3086513548163922365 |
MoPub (deprecated) | 10872986198578383917 |
myTarget | 8450873672465271579 |
Nend | 9383070032774777750 |
Nexxen (bidding)* * Prior to May 1, 2024, this network was called "UnrulyX". | 2831998725945605450 |
ONE by AOL (Millennial Media) | 6101072188699264581 |
ONE by AOL (Nexage) | 3224789793037044399 |
OneTag Exchange (bidding) | 4873891452523427499 |
OpenX (bidding) | 4918705482605678398 |
Pangle | 4069896914521993236 |
Pangle (bidding) | 3525379893916449117 |
PubMatic (bidding) | 3841544486172445473 |
Reservation campaign | 7068401028668408324 |
RhythmOne (bidding) | 2831998725945605450 |
Rubicon (bidding) | 3993193775968767067 |
SK planet | 734341340207269415 |
Sharethrough (bidding) | 5247944089976324188 |
Smaato (bidding) | 3362360112145450544 |
Equativ (bidding)* * Prior to January 12, 2023, this network was called "Smart Adserver". | 5970199210771591442 |
Sonobi (bidding) | 3270984106996027150 |
Tapjoy | 7295217276740746030 |
Tapjoy (bidding) | 4692500501762622178 |
Tencent GDT | 7007906637038700218 |
TripleLift (bidding) | 8332676245392738510 |
Unity Ads | 4970775877303683148 |
Unity Ads (bidding) | 7069338991535737586 |
Verizon Media | 7360851262951344112 |
Verve Group (bidding) | 5013176581647059185 |
Vpon | 1940957084538325905 |
Liftoff Monetize* * Prior to January 30, 2023, this network was called "Vungle". | 1953547073528090325 |
Liftoff Monetize (bidding)* * Prior to January 30, 2023, this network was called "Vungle (bidding)". | 4692500501762622185 |
Yieldmo (bidding) | 4193081836471107579 |
YieldOne (bidding) | 3154533971590234104 |
Zucks | 5506531810221735863 |
Nutzer belohnen
Es ist wichtig, bei der Entscheidung ein Gleichgewicht zwischen User Experience und Validierung der Prämie zu finden. wann Nutzende belohnen sollen. Bei serverseitigen Callbacks kann es vor dem externe Systeme zu erreichen. Daher empfiehlt es sich, den clientseitigen Callback, um den Nutzer sofort zu belohnen, während Überprüfung aller Prämien nach Erhalt von serverseitigen Callbacks. Dieses eine gute User Experience bietet und gleichzeitig die Gültigkeit der gewährten Prämien.
Bei Anwendungen, bei denen die Gültigkeit von Prämien entscheidend ist (z. B. hat Auswirkungen auf die In-Game-Ökonomie Ihrer App. Außerdem kann es zu Verzögerungen bei der Vergabe von Prämien kommen. akzeptabel ist, warten Sie am besten auf den verifizierten serverseitigen Rückruf. Ansatz.
Benutzerdefinierte Daten
Apps, die zusätzliche Daten in Callbacks zur serverseitigen Überprüfung benötigen, sollten Folgendes verwenden:
die Funktion für benutzerdefinierte Daten
von Anzeigen mit Prämie. Beliebiger Stringwert, der in einer Anzeige mit Prämie festgelegt ist
wird an den custom_data
-Abfrageparameter des SSV-Callbacks übergeben. Falls nein
festgelegt ist, ist der Wert des Suchparameters custom_data
nicht gleich
im SSV-Callback vorhanden sind.
Im folgenden Codebeispiel wird gezeigt, wie die SSV-Optionen nach dem Anzeige mit Prämie wurde geladen.
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 } })
Wenn Sie den benutzerdefinierten Prämienstring festlegen möchten, müssen Sie dies vor der Anzeige tun der Anzeige.
Manuelle Bestätigung der SSV mit Prämie
Die Schritte, die von der Klasse „RewardedAdsVerifier
“ ausgeführt werden, um eine Prämie zu bestätigen
Die serverseitige Überprüfung wird im Folgenden beschrieben. Die enthaltenen Code-Snippets sind zwar in Java,
die Tink-Drittanbieterbibliothek nutzen, können Sie diese Schritte
in der Sprache Ihrer Wahl. Verwenden Sie dazu eine Drittanbieterbibliothek, die
ECDSA:
Öffentliche Schlüssel abrufen
Zum Bestätigen eines Callbacks für eine SSV mit Prämie benötigen Sie einen von AdMob bereitgestellten öffentlichen Schlüssel.
Eine Liste mit öffentlichen Schlüsseln, mit denen die SSV-Callbacks mit Prämie validiert werden können aus dem AdMob-Schlüssel Server. Die Liste der öffentlichen Schlüssel wird als JSON-Darstellung in einem Format wie dem folgenden bereitgestellt:
{
"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=="
},
],
}
Stellen Sie zum Abrufen der öffentlichen Schlüssel eine Verbindung zum AdMob-Schlüsselserver her und laden Sie den
Schlüssel. Der folgende Code führt diese Aufgabe durch und speichert die JSON-Datei
Darstellung der Schlüssel für die Variable 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();
}
Beachten Sie, dass öffentliche Schlüssel regelmäßig rotiert werden. Sie werden per E-Mail darüber informiert. eine bevorstehende Rotation. Wenn Sie öffentliche Schlüssel im Cache speichern, sollten Sie erhalten Sie nach Erhalt dieser E-Mail die Schlüssel.
Sobald die öffentlichen Schlüssel abgerufen wurden, müssen sie geparst werden. Die
Für die Methode parsePublicKeysJson
unten wird ein JSON-String wie im Beispiel verwendet
und erstellt eine Zuordnung von key_id
-Werten zu öffentlichen Schlüsseln.
die als ECPublicKey
-Objekte aus der Tink-Bibliothek gekapselt sind.
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;
}
Inhalte bestätigen lassen
Die letzten beiden Suchparameter von SSV-Callbacks mit Prämie sind immer signature
und key_id,
in dieser Reihenfolge. Die verbleibenden Suchparameter
geben den Inhalt an,
noch nicht bestätigt werden. Angenommen, Sie haben AdMob so konfiguriert, dass Rückrufe für Prämien
https://www.myserver.com/mypath
Das Snippet unten zeigt ein Beispiel für eine Anzeige mit Prämie
SSV-Rückruf mit hervorgehobenem Inhalt
https://www.myserver.com/path?ad_network=54...55&ad_unit=12345678&reward_amount=10&reward_item=coins ×tamp=150777823&transaction_id=12...DEF&user_id=1234567&signature=ME...Z1c&key_id=1268887
Der folgende Code zeigt, wie der zu überprüfende Inhalt von einem -Callback-URL als UTF-8-Byte-Array.
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"));
Signatur und key_id aus Callback-URL abrufen
Mit dem Wert queryString
aus dem vorherigen Schritt parsen Sie signature
und
key_id
-Abfrageparameter aus der Callback-URL, wie unten dargestellt:
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()));
Überprüfung durchführen
Der letzte Schritt besteht darin, den Inhalt der Callback-URL mit der Methode
entsprechenden öffentlichen Schlüssel. Nehmen Sie die Zuordnung, die vom
parsePublicKeysJson
-Methode und verwenden Sie den key_id
-Parameter aus dem Callback.
URL zum Abrufen des öffentlichen Schlüssels aus dieser Zuordnung. Bestätigen Sie dann die Signatur mit
diesen öffentlichen Schlüssel. Diese Schritte werden unten in der Methode verify
beschrieben.
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);
}
}
Wird die Methode ohne Ausnahme ausgeführt, lautete die Callback-URL: wurde bestätigt.
FAQ
- Kann ich den vom AdMob-Schlüsselserver bereitgestellten öffentlichen Schlüssel im Cache speichern?
- Wir empfehlen, den vom AdMob-Schlüssel bereitgestellten öffentlichen Schlüssel im Cache zu speichern Server, um die Anzahl der Vorgänge zur Validierung der SSV-Datei zu reduzieren Callbacks angegeben werden. Beachten Sie jedoch, dass öffentliche Schlüssel regelmäßig rotiert werden und nicht länger als 24 Stunden im Cache gespeichert werden.
- Wie oft werden die vom AdMob-Schlüsselserver bereitgestellten öffentlichen Schlüssel rotiert?
- Vom AdMob-Schlüsselserver bereitgestellte öffentliche Schlüssel werden für eine Variable rotiert ein. Um sicherzustellen, dass SSV-Rückrufe weiterhin funktionieren, sollten öffentliche Schlüssel nicht länger als 24 Stunden im Cache gespeichert werden.
- Was passiert, wenn mein Server nicht erreichbar ist?
- Google erwartet einen Erfolgsstatusantwortcode für die serverseitige Überprüfung von
HTTP 200 OK
Callbacks angegeben werden. Wenn Ihr Server nicht erreichbar ist oder nicht den erwarteten antwortet, versucht Google bis zu fünfmal ein-Sekunden-Intervall. - Wie kann ich prüfen, ob SSV-Rückrufe von Google stammen?
- Mit dem umgekehrten DNS-Lookup können Sie prüfen, ob die SSV-Rückrufe von Google stammen.