I callback di verifica lato server sono richieste di URL con parametri di ricerca espansi da Google, che vengono inviati da Google a un sistema esterno per informarlo che un utente deve essere premiato per l'interazione con un annuncio interstitial con premio o con premio. I callback SSV (verifica lato server) con premio offrono un ulteriore livello di protezione contro lo spoofing dei callback lato client per premiare gli utenti.
Questa guida illustra come verificare i callback SSV con premio utilizzando la libreria crittografica di terze parti Tink per garantire che i parametri di ricerca nel callback siano valori legittimi. Sebbene Tink venga utilizzato ai fini di questa guida, hai la possibilità di utilizzare qualsiasi libreria di terze parti che supporta ECDSA. Puoi anche testare il tuo server con lo strumento di test nell'interfaccia utente di AdMob.
Guarda questo esempio pienamente funzionante utilizzando Java boot-boot.
Prerequisiti
Integra gli annunci con premio nella tua app per dispositivi mobili con11.6.0 o versioni successive dell'SDK Google Mobile Ads.
Attiva la verifica lato server con premio sull'unità pubblicitaria.
Usa RewardAdsVerifier da Tink
Il repository GitHub Tink include una classe helper RewardedAdsVerifier
per ridurre il codice necessario per verificare un callback SSV con premio.
L'utilizzo di questa classe insieme alla libreria crittografica di terze parti Tink 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, l'URL di callback è stato verificato. La sezione Premiare l'utente descrive in dettaglio le best practice relative a quando gli utenti dovrebbero essere premiati. Per un'analisi dei passaggi eseguiti da questo corso per verificare i callback SSV con premio,
consulta la sezione Verifica manuale della SSV con premio.
Parametri di callback SSV
I callback di verifica lato server contengono parametri di ricerca che descrivono l'interazione con l'annuncio con premio. Di seguito sono elencati i nomi dei parametri, le descrizioni e i valori di esempio. I parametri vengono inviati in ordine alfabetico.
Nome parametro | Descrizione | Valore di esempio |
---|---|---|
ad_network | Identificatore dell'origine annuncio che ha soddisfatto l'annuncio. I nomi delle origini annuncio corrispondenti ai valori ID sono elencati nella sezione Identificatori dell'origine annuncio. | 1953547073528090325 |
unità_pubblicitaria | ID unità pubblicitaria di AdMob utilizzato per richiedere l'annuncio con premio. | 2747237135 |
dati_personalizzati | Stringa di dati personalizzata fornita da
setCustomData
.
Se l'app non fornisce una stringa di dati personalizzata, il valore del parametro di ricerca non sarà presente nel callback SSV. |
SAMPLE_CUSTOM_DATA_STRING |
key_id (id_chiave) | Chiave da utilizzare per verificare il callback SSV. Questo valore viene mappato a una chiave pubblica fornita dal server chiavi AdMob. | 1234567890 |
premio_importo | Importo del premio specificato nelle impostazioni dell'unità pubblicitaria. | 5 |
premio_articolo | Premio relativo all'elemento come specificato nelle impostazioni dell'unità pubblicitaria. | monete |
firma | Firma per il callback SSV generato da AdMob. | MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY |
timestamp | Timestamp che indica quando l'utente ha ricevuto un premio come periodo del periodo 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
setUserId .
Se l'app non fornisce alcun identificatore utente, questo parametro di ricerca non sarà presente nel callback SSV. |
1234567 |
Identificatori delle origini annuncio
Nomi e ID origine annuncio
Nome origine annuncio | ID origine annuncio |
---|---|
Aarki (offerte) | 5240798063227064260 |
Generazione di annunci (offerte) | 1477265452970951479 |
AdColony | 15586990674969969776 |
AdColony (non SDK) (Asta) | 4600416542059544716 |
AdColony (offerte) | 6895345910719072481 |
AdFalcon | 3528208921554210682 |
Rete AdMob | 5450213213286189855 |
Risultato AD | 10593873382626181482 |
AMoAd | 17253994435944008978 |
Applovin | 1063618907739174004 |
Applovin (asta) | 1328079684332308356 |
Grafico di tendenza | 2873236629771172317 |
Piattaforma cioccolato (offerte) | 6432849193975106527 |
Crosschannel (MdotM) | 9372067028804390441 |
Evento personalizzato | 18351550913290782395 |
DT Exchange Prima del 21 settembre 2022, questa rete era chiamata "Fyber". | 4839637394546996422 |
Fluct (offerte) | 8419777862490735710 |
Raffiche | 3376427960656545613 |
i-mobile | 5208827440166355534 |
Migliora il digitale (offerte) | 159382223051638006 |
Scambio dell'indice (Asta) | 4100650709078789802 |
InMobi | 7681903010231960328 |
InMobi (Asta) | 6325663098072678541 |
Fonte di ferro | 6925240245545091930 |
Leadbolt | 2899150749497968595 |
LG U + ANNUNCIO | 18298738678491729107 |
Maio | 7505118203095108657 |
maio (offerte) | 1343336733822567166 |
Media.net (offerte) | 2127936450554446159 |
Annunci autopromozionali con mediazione | 6060308706800320801 |
Meta Audience Network Prima del 6 giugno 2022, questa rete era chiamata "Facebook Audience Network". | 10568273599589928883 |
Meta Audience Network (offerte) Prima del 6 giugno 2022, questa rete era chiamata "Facebook Audience Network (offerte)". | 11198165126854996598 |
MobFox | 8079529624516381459 |
MoPub (deprecato) | 10872986198578383917 |
myTarget | 8450873672465271579 |
Nend | 9383070032774777750 |
ONE di AOL (Millennial Media) | 6101072188699264581 |
ONE di AOL (Nexage) | 3224789793037044399 |
OpenX (Asta) | 4918705482605678398 |
Pangle (asta) | 3525379893916449117 |
PubMatic (Asta) | 3841544486172445473 |
Campagna basata su prenotazione | 7068401028668408324 |
RhythmOne (asta) | 2831998725945605450 |
Rubicon (Asta) | 3993193775968767067 |
pianeta SK | 734341340207269415 |
Sharethrough (asta) | 5247944089976324188 |
Smaato (offerte) | 3362360112145450544 |
Equativ (asta)* * Prima del 12 gennaio 2023, questa rete era chiamata "Smart Adserver". | 5970199210771591442 |
Sonobi (asta) | 3270984106996027150 |
Tapjoy | 7295217276740746030 |
Tapjoy (offerte) | 4692500501762622178 |
GDT Tencent | 7007906637038700218 |
TripleLift (Asta) | 8332676245392738510 |
Annunci Unity | 4970775877303683148 |
UnrulyX (Asta) | 2831998725945605450 |
Media Verizon | 7360851262951344112 |
Vpon | 1940957084538325905 |
Decollo Monetizzazione* * Prima del 30 gennaio 2023, questa rete era chiamata "Vungle". | 1953547073528090325 |
Incremento del prodotto Monetizza (offerta)* * Prima del 30 gennaio 2023, questa rete era chiamata "Vungle". | 4692500501762622185 |
YieldMo (asta) | 4193081836471107579 |
YieldOne (asta) | 3154533971590234104 |
Zucks | 5506531810221735863 |
Premiare l'utente
È importante bilanciare l'esperienza utente e premiare la convalida quando si decide quando assegnare un premio a un utente. I callback lato server potrebbero subire ritardi prima di raggiungere i sistemi esterni. Pertanto, la best practice consigliata è utilizzare il callback lato client per premiare immediatamente l'utente e allo stesso tempo eseguire la convalida su tutti i premi al ricevimento dei callback lato server. Questo approccio offre una buona esperienza utente, garantendo al contempo la validità dei premi concessi.
Tuttavia, per le applicazioni in cui la validità dei premi è fondamentale (ad esempio, il premio influisce sull'economia in-game dell'app) e i ritardi nella concessione dei premi sono accettabili, attendere il callback lato server verificato potrebbe essere l'approccio migliore.
Dati personalizzati
Le app che richiedono dati aggiuntivi nei callback di verifica lato server dovrebbero utilizzare
la funzionalità dei dati personalizzati degli annunci con premio. Qualsiasi valore stringa impostato su un oggetto dell'annuncio con premio
viene trasmesso al parametro di ricerca custom_data
del callback SSV. Se non viene impostato alcun valore di dati personalizzati, 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 caricamento dell'annuncio con premio.
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 } })
Se vuoi impostare una stringa di premi personalizzata, devi farlo prima di pubblicare l'annuncio.
Verifica manuale della SSV con premio
I passaggi eseguiti dalla classe RewardedAdsVerifier
per verificare un
SVS con premio sono descritti di seguito. Anche se gli snippet di codice inclusi si trovano in Java e utilizzano la libreria di terze parti di Tink, questi passaggi possono essere implementati da te nel linguaggio preferito, utilizzando qualsiasi libreria di terze parti che supporta ECDSA.
Recupera chiavi pubbliche
Per verificare un callback SSV con premio, devi avere una chiave pubblica fornita da AdMob.
Un elenco delle chiavi pubbliche da utilizzare per convalidare i callback SSV con premio può essere recuperato dal server delle chiavi AdMob. 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, connettiti al server delle chiavi AdMob e scarica le chiavi. Il codice seguente esegue questa attività e salva la rappresentazione JSON delle chiavi nella 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 fatte ruotare regolarmente. Riceverai un'email relativa all'imminente rotazione. Se stai memorizzando nella cache le chiavi pubbliche, devi aggiornarle quando ricevi questa email.
Dopo essere state recuperate, le chiavi pubbliche devono essere analizzate. Il metodo parsePublicKeysJson
riportato di seguito prende come stringa una stringa JSON, come nell'esempio riportato sopra, e crea una mappatura dai valori key_id
alle chiavi pubbliche, 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 ricerca dei callback SSV con premio sono sempre signature
e key_id,
in questo ordine. I restanti parametri di ricerca specificano i contenuti da verificare. Supponiamo che tu abbia configurato AdMob per inviare i callback del premio a
https://www.myserver.com/mypath
. Lo snippet seguente mostra un esempio di callback SSV con premio in cui sono evidenziati i contenuti da verificare.
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 illustra come analizzare i contenuti da verificare da un URL di callback come 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 firma e key_id dall'URL di callback
Utilizzando il valore queryString
del passaggio precedente, analizza i parametri di ricerca signature
e
key_id
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 nella verifica dei contenuti dell'URL di callback con la chiave pubblica appropriata. Togli la mappatura restituita dal metodo parsePublicKeysJson
e utilizza il parametro key_id
dall'URL di callback per recuperare la chiave pubblica da quella mappatura. Verifica quindi la firma con quella chiave pubblica. Questi passaggi sono dimostrati 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 è stato verificato.
Domande frequenti
- Posso memorizzare nella cache la chiave pubblica fornita dal server delle chiavi AdMob?
- Ti consigliamo di memorizzare nella cache la chiave pubblica fornita dal server delle chiavi AdMob per ridurre il numero di operazioni necessarie per convalidare i callback SSV. 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 delle chiavi AdMob vengono ruotate in base a una pianificazione di variabili. Per garantire che la verifica dei callback SSV continui a funzionare come previsto, le chiavi pubbliche non devono essere memorizzate nella cache per più di 24 ore.
- Cosa succede se il mio server non può essere raggiunto?
- Google prevede un codice di risposta stato
HTTP 200 OK
per i callback di SSV. Se il server non può essere raggiunto o non fornisce la risposta prevista, Google tenterà di inviare di nuovo i callback SSV fino a cinque volte a intervalli di un secondo. - Come faccio a verificare che i callback SSV provengano da Google?
- Utilizza la ricerca DNS inversa per verificare che i callback SSV provengano da Google.