I callback di verifica lato server sono richieste URL con parametri di query espanse da Google, inviate da Google a un sistema esterno per comunicagli che un utente deve essere premiato per aver interagito con un premio annuncio interstitial con premio. Callback SSV (verifica lato server) premiato offrono un ulteriore livello di protezione contro lo spoofing dei callback lato client per premiare gli utenti.
Questa guida mostra come verificare i callback della verifica lato server con premio utilizzando il App Java Tink di terze parti libreria crittografica per garantire che i parametri di query nel callback valori legittimi. Anche se Tink è utilizzato ai fini di questa guida, hai la possibilità di utilizzare qualsiasi libreria di terze parti che supporti ECDSA. Puoi anche testare il server con nell'interfaccia utente di AdMob.
Dai un'occhiata a questo video esempio usando Spring-boot Java.
Prerequisiti
Integra gli annunci con premio nel tuo app mobile con Versione 7.28.0 o successiva dell'SDK Google Mobile Ads.
Attiva con premio lato server verifica sulla tua unità pubblicitaria.
Utilizza RewardAdsVerifier dalla raccolta di app Java di Tink
Il repository GitHub delle app Java Tink
include un oggetto
RewardedAdsVerifier
:
per ridurre il codice necessario per verificare un callback di SSV con premio.
Questa classe ti consente di verificare un URL di callback con il seguente codice.
RewardedAdsVerifier verifier = new RewardedAdsVerifier.Builder()
.fetchVerifyingPublicKeysWith(
RewardedAdsVerifier.KEYS_DOWNLOADER_INSTANCE_PROD)
.build();
String rewardUrl = ...;
verifier.verify(rewardUrl);
Se il metodo verify()
viene eseguito senza generare un'eccezione, il callback
L'URL è stato verificato. L'opzione Ricompensare l'utente
descrive in dettaglio le best practice relative a quando gli utenti devono essere premiati. Per un
dei passaggi eseguiti da questa classe per verificare i callback della verifica lato server con premio
puoi leggere le istruzioni della verifica manuale degli annunci
.
Parametri callback SSV
I callback di verifica lato server contengono parametri di query che descrivono interazione con l'annuncio con premio. Nomi dei parametri, descrizioni e valori di esempio sono elencati di seguito. I parametri vengono inviati in ordine alfabetico.
Nome parametro | Descrizione | Valore di esempio |
---|---|---|
ad_network | Identificatore dell'origine annuncio che ha pubblicato questo annuncio. Origine annuncio nomi corrispondenti ai valori ID sono indicati nella scheda identificatori di origine. | 1953547073528090325 |
ad_unit | L'ID unità pubblicitaria AdMob utilizzato per richiedere l'annuncio con premio. | 2747237135 |
custom_data | Stringa di dati personalizzata fornita da
customRewardString
.
Se l'app non fornisce alcuna stringa di dati personalizzata, questo parametro di query non sarà presente nel callback SSV. |
SAMPLE_CUSTOM_DATA_STRING |
key_id | Chiave da utilizzare per verificare il callback SSV. Questo valore è mappato a una chiave pubblica forniti dal server delle chiavi AdMob. | 1234567890 |
reward_amount | Importo del premio specificato nelle impostazioni dell'unità pubblicitaria. | 5 |
reward_item | Premio come specificato nelle impostazioni dell'unità pubblicitaria. | monete |
firma | Firma per il callback della verifica lato client generato da AdMob. | MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY |
timestamp | Timestamp del momento in cui l'utente è stato premiato come tempo dell'epoca in ms. | 1507770365237823 |
transaction_id | Identificatore univoco codificato esadecimale per ogni evento di concessione di premi generato da AdMob. | 18fa792de1bca816048293fc71035638 |
user_id | Identificatore utente fornito da
userIdentifier
Se l'app non fornisce alcun identificatore utente, questo parametro di query non nel callback SSV. |
1234567 |
Identificatori delle origini annuncio
Nomi e ID delle origini annuncio
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 |
Ricompensare l'utente
Al momento di decidere, è importante trovare un equilibrio tra l'esperienza utente e la convalida dei premi quando premiare un utente. Le callback lato server potrebbero subire ritardi prima che raggiungono i sistemi esterni. Pertanto, la best practice consigliata è utilizzare il callback lato client per ricompensare immediatamente l'utente mentre esegue la convalida di tutti i premi al ricevimento dei callback lato server. Questo offre una buona esperienza utente garantendo al contempo la validità premi.
Tuttavia, per le richieste in cui la validità del premio è fondamentale (ad esempio, premio incide sull'economia in-game della tua app), mentre i ritardi nella concessione dei premi sono accettabile, l'attesa della richiamata lato server verificata potrebbe essere la scelta migliore l'importanza di un approccio umile.
Dati personalizzati
Le app che richiedono dati aggiuntivi nei callback di verifica lato server devono utilizzare
la funzionalità dei dati personalizzati
degli annunci con premio. Qualsiasi valore di stringa impostato su un annuncio con premio
viene passato al parametro di query custom_data
del callback SSV. In caso contrario
valore dei dati personalizzati è impostato, il valore del parametro di ricerca custom_data
non sarà
presente nel callback SSV.
Il seguente esempio di codice mostra come impostare le opzioni SSV dopo il comando l'annuncio con premio è stato caricato.
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; }];
Verifica manuale della verifica lato server con premio
I passaggi eseguiti dalla classe RewardedAdsVerifier
per verificare un premio
la verifica lato server è descritta di seguito. Anche se gli snippet di codice inclusi sono in Java
usare la libreria di terze parti Tink, puoi implementare questi passaggi
la lingua che preferisci, utilizzando qualsiasi libreria di terze parti che supporti
ECDSA.
Recupera chiavi pubbliche
Per verificare il callback della verifica lato server con premio, devi avere una chiave pubblica fornita da AdMob.
È possibile utilizzare un elenco di chiavi pubbliche da utilizzare per convalidare i callback della verifica lato server con premio recuperata dalla chiave AdMob o server web. L'elenco delle chiavi pubbliche viene fornito come rappresentazione JSON con un formato simile al seguente:
{
"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=="
},
],
}
Per recuperare le chiavi pubbliche, collegati al server delle chiavi AdMob e scarica
chiave. Il codice seguente esegue questa attività e salva il file JSON
delle chiavi alla variabile 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();
}
Tieni presente che le chiavi pubbliche vengono ruotate regolarmente. Riceverai un'email per informarti di una rotazione imminente. Se stai memorizzando nella cache le chiavi pubbliche, devi aggiornare le chiavi alla ricezione di questa email.
Una volta recuperate, le chiavi pubbliche devono essere analizzate. La
Il metodo parsePublicKeysJson
seguente utilizza una stringa JSON, come quella dell'esempio
sopra, come input, e crea una mappatura dai valori key_id
alle chiavi pubbliche,
che sono incapsulati come oggetti ECPublicKey
dalla libreria Tink.
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;
}
Richiedi la verifica dei contenuti
Gli ultimi due parametri di query dei callback SSV con premio sono sempre signature
e key_id,
in quell'ordine. I restanti parametri di query specificano i contenuti
da verificare. Supponiamo che tu abbia configurato AdMob per l'invio dei callback dei premi a
https://www.myserver.com/mypath
. Lo snippet seguente mostra un esempio di premio
Callback SSV con i contenuti da verificare evidenziati.
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
Il codice seguente mostra come analizzare i contenuti da verificare da un come un array di byte 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"));
Ottieni la firma e il key_id dall'URL di callback
Utilizzando il valore queryString
del passaggio precedente, analizza i signature
e
key_id
parametri di query dall'URL di callback, come mostrato di seguito:
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()));
Esegui la verifica
Il passaggio finale consiste nel verificare i contenuti dell'URL di callback con il parametro
chiave pubblica appropriata. Prendi il mapping restituito dal
parsePublicKeysJson
e usa il parametro key_id
del callback
URL per ottenere la chiave pubblica dal mapping. Poi verifica la firma con
della chiave pubblica. Questi passaggi sono mostrati di seguito nel metodo 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);
}
}
Se il metodo viene eseguito senza generare un'eccezione, l'URL di callback verificato correttamente.
Domande frequenti
- Posso memorizzare nella cache la chiave pubblica fornita dal server della chiave AdMob?
- Ti consigliamo di memorizzare nella cache la chiave pubblica fornita dalla chiave AdMob. per ridurre il numero di operazioni necessarie per convalidare la verifica lato server i callback. Tuttavia, tieni presente che le chiavi pubbliche vengono ruotate regolarmente e non devono essere memorizzate nella cache per più di 24 ore.
- Con quale frequenza vengono ruotate le chiavi pubbliche fornite dal server delle chiavi AdMob?
- Le chiavi pubbliche fornite dal server chiavi di AdMob vengono ruotate in base a una variabile programmazione. Per garantire che la verifica dei callback di SSV continui a funzionare come le chiavi pubbliche non devono essere memorizzate nella cache per più di 24 ore.
- Cosa succede se il mio server non è raggiungibile?
- Google si aspetta un codice di risposta relativo allo stato di operazione riuscita per
HTTP 200 OK
i callback. Se non è possibile raggiungere il server o non fornisce la risposta prevista risposta, Google tenterà nuovamente di inviare i callback SSV fino a cinque volte in intervalli di 1 secondo. - Come faccio a verificare che i callback di SSV provengano da Google?
- Utilizza la ricerca DNS inversa per verificare che i callback SSV provengano da Google.