Wywołania zwrotne w ramach weryfikacji po stronie serwera to żądania URL z rozwiniętymi przez Google parametrami zapytania, które Google wysyła do systemu zewnętrznego, aby powiadomić go, że użytkownik powinien otrzymać nagrodę za interakcję z reklamą przejściową z nagrodą lub reklamą przejściową z nagrodą. Wywołania zwrotne po stronie serwera (weryfikacja po stronie serwera) w przypadku reklam z nagrodą zapewniają dodatkową ochronę przed podszywaniem wywołań zwrotnych po stronie klienta w celu nagradzania użytkowników.
Z tego przewodnika dowiesz się, jak weryfikować wywołania zwrotne SSV z nagrodą za pomocą zewnętrznej biblioteki kryptograficznej Tink Java Apps, aby upewnić się, że parametry zapytania w wywołaniu zwrotnym to prawidłowe wartości. Chociaż w tym przewodniku używamy biblioteki Tink, możesz użyć dowolnej biblioteki zewnętrznej, która obsługuje ECDSA. Możesz też przetestować serwer za pomocą narzędzia do testowania w interfejsie AdMob.
Wymagania wstępne
- Włącz w jednostce reklamowej weryfikację po stronie serwera dotyczącą reklam z nagrodą.
Używanie biblioteki RewardedAdsVerifier z biblioteki aplikacji Tink w języku Java
Repozytorium GitHub Tink Java Apps zawiera klasę pomocniczą RewardedAdsVerifier
, która pozwala ograniczyć kod wymagany do weryfikacji wywołania zwrotnego SSV z nagrodą.
Za pomocą tej klasy możesz zweryfikować adres URL wywołania zwrotnego za pomocą tego kodu.
RewardedAdsVerifier verifier = new RewardedAdsVerifier.Builder()
.fetchVerifyingPublicKeysWith(
RewardedAdsVerifier.KEYS_DOWNLOADER_INSTANCE_PROD)
.build();
String rewardUrl = ...;
verifier.verify(rewardUrl);
Jeśli metoda verify()
zostanie wykonana bez wywołania wyjątku, adres URL wywołania zwrotnego został pomyślnie zweryfikowany. W sekcji Nagrywanie użytkownika znajdziesz sprawdzone metody dotyczące tego, kiedy należy nagradzać użytkowników. Szczegóły dotyczące czynności wykonywanych przez tę klasę w celu weryfikacji wywołań zwrotnych SSV z nagrodą znajdziesz w sekcji Ręczne sprawdzanie wywołań zwrotnych SSV z nagrodą.
Parametry wywołania zwrotnego SSV
Wywołania zwrotne w ramach weryfikacji po stronie serwera zawierają parametry zapytania opisujące interakcję z reklamą wideo z nagrodą. Nazwy, opisy i przykładowe wartości parametrów znajdziesz poniżej. Parametry są wysyłane w kolejności alfabetycznej.
Nazwa parametru | Opis | Przykładowa wartość |
---|---|---|
ad_network | Identyfikator źródła reklam, które dostarczyło tę reklamę. Nazwy źródeł reklam odpowiadające wartościom identyfikatorów są wymienione w sekcji Identyfikatory źródeł reklam. | 1953547073528090325 |
ad_unit | Identyfikator jednostki reklamowej AdMob, która została użyta do wysłania żądania reklamy z nagrodą. | 2747237135 |
key_id | Klucz służący do weryfikacji wywołania zwrotnego SSV. Ta wartość jest mapowana na klucz publiczny udostępniany przez serwer kluczy AdMob. | 1234567890 |
reward_amount | kwota nagrody określona w ustawieniach jednostki reklamowej. | 5 |
reward_item | Nagroda określona w ustawieniach jednostki reklamowej. | monety |
podpis | podpis wywołania zwrotnego SSV wygenerowany przez AdMob. | MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY |
sygnatura czasowa | Sygnatura czasowa momentu, w którym użytkownik otrzymał nagrodę, w milisekundach. | 1507770365237823 |
transaction_id | Unikalny identyfikator zakodowany w szesnastkowym kodzie dziesiętnym dla każdego zdarzenia przyznania nagrody wygenerowanego przez AdMob. | 18fa792de1bca816048293fc71035638 |
user_id | Identyfikator użytkownika podany przez użytkownika:
SetUserId .
Jeśli aplikacja nie poda identyfikatora użytkownika, ten parametr zapytania nie będzie obecny w wywołaniu zwrotnym SSV. |
1234567 |
Identyfikatory źródeł reklam
Nazwy i identyfikatory źródeł reklam
Nazwa źródła reklamy | Identyfikator źródła reklamy |
---|---|
Aarki (określanie stawek) | 5240798063227064260 |
Generowanie reklam (określanie stawek) | 1477265452970951479 |
AdColony | 15586990674969969776 |
AdColony (bez pakietu SDK) (określanie stawek) | 4600416542059544716 |
AdColony (określanie stawek) | 6895345910719072481 |
AdFalcon | 3528208921554210682 |
Sieć AdMob | 5450213213286189855 |
Kaskada sieci AdMob | 1215381445328257950 |
ADResult | 10593873382626181482 |
AMoAd | 17253994435944008978 |
AppLovin | 1063618907739174004 |
AppLovin (określanie stawek) | 1328079684332308356 |
Chartboost | 2873236629771172317 |
Chocolate Platform (określanie stawek) | 6432849193975106527 |
Cross-Channel (MdotM) | 9372067028804390441 |
Zdarzenie niestandardowe | 18351550913290782395 |
DT Exchange* * Przed 21 września 2022 r. sieć ta nazywała się „Fyber Marketplace”. | 2179455223494392917 |
EMX (określanie stawek) | 8497809869790333482 |
Fluct (określanie stawek) | 8419777862490735710 |
Druzgocąca seria | 3376427960656545613 |
Fyber* * To źródło reklam służy do raportowania historycznego. | 4839637394546996422 |
i-mobile | 5208827440166355534 |
Improve Digital (bidding) | 159382223051638006 |
Index Exchange (ustalanie stawek) | 4100650709078789802 |
InMobi | 7681903010231960328 |
InMobi (określanie stawek) | 6325663098072678541 |
InMobi Exchange (ustalanie stawek) | 5264320421916134407 |
IronSource | 6925240245545091930 |
ironSource Ads (ustalanie stawek) | 1643326773739866623 |
Leadbolt | 2899150749497968595 |
LG U+AD | 18298738678491729107 |
Sieć LINE Ads | 3025503711505004547 |
maio | 7505118203095108657 |
maio (określanie stawek) | 1343336733822567166 |
Media.net (określanie stawek) | 2127936450554446159 |
Zapośredniczone autoreklamy | 6060308706800320801 |
Meta Audience Network* * Do 6 czerwca 2022 r. sieć nosiła nazwę „Facebook Audience Network”. | 10568273599589928883 |
Meta Audience Network (ustalanie stawek)* * Przed 6 czerwca 2022 r. sieć ta nosiła nazwę „Facebook Audience Network (ustalanie stawek)”. | 11198165126854996598 |
Mintegral | 1357746574408896200 |
Mintegral (określanie stawek) | 6250601289653372374 |
MobFox | 8079529624516381459 |
MobFox (określanie stawek) | 3086513548163922365 |
MoPub (wycofany) | 10872986198578383917 |
myTarget | 8450873672465271579 |
Nend | 9383070032774777750 |
Nexxen (określanie stawek)* * Przed 1 maja 2024 r. sieć ta nazywała się „UnrulyX”. | 2831998725945605450 |
ONE by AOL (Millennial Media) | 6101072188699264581 |
ONE by AOL (Nexage) | 3224789793037044399 |
OneTag Exchange (ustalanie stawek) | 4873891452523427499 |
OpenX (określanie stawek) | 4918705482605678398 |
Pangle | 4069896914521993236 |
Pangle (określanie stawek) | 3525379893916449117 |
PubMatic (określanie stawek) | 3841544486172445473 |
Kampania z rezerwacją | 7068401028668408324 |
RhythmOne (określanie stawek) | 2831998725945605450 |
Rubicon (określanie stawek) | 3993193775968767067 |
SK planet | 734341340207269415 |
Sharethrough (określanie stawek) | 5247944089976324188 |
Smaato (określanie stawek) | 3362360112145450544 |
Equativ (określanie stawek)* * Przed 12 stycznia 2023 r. sieć ta nazywała się „Inteligentny serwer reklamowy”. | 5970199210771591442 |
Sonobi (określanie stawek) | 3270984106996027150 |
Tapjoy | 7295217276740746030 |
Tapjoy (określanie stawek) | 4692500501762622178 |
Tencent GDT | 7007906637038700218 |
TripleLift (określanie stawek) | 8332676245392738510 |
Unity Ads | 4970775877303683148 |
Unity Ads (określanie stawek) | 7069338991535737586 |
Verizon Media | 7360851262951344112 |
Verve Group (określanie stawek) | 5013176581647059185 |
Vpon | 1940957084538325905 |
Liftoff Monetize* * Przed 30 stycznia 2023 r. sieć ta nazywała się „Vungle”. | 1953547073528090325 |
Liftoff Monetize (ustalanie stawek)* * Przed 30 stycznia 2023 r. sieć ta nazywała się „Vungle (określanie stawek)”. | 4692500501762622185 |
Yieldmo (określanie stawek) | 4193081836471107579 |
YieldOne (określanie stawek) | 3154533971590234104 |
Zucks | 5506531810221735863 |
Nagrywanie użytkownika
Decydując, kiedy przyznać nagrodę użytkownikowi, należy zachować równowagę między jego wrażeniami a weryfikacją nagrody. Wywołania zwrotne po stronie serwera mogą być opóźnione przed dotarciem do systemów zewnętrznych. Dlatego zalecamy, aby używać wywołania zwrotnego po stronie klienta, aby natychmiast nagrodzić użytkownika, a po otrzymaniu wywołań zwrotnych po stronie serwera przeprowadzić weryfikację wszystkich nagród. Takie podejście zapewnia użytkownikom dobre wrażenia, a zarazem gwarantuje ważność przyznanych nagród.
W przypadku aplikacji, w których ważność nagrody jest kluczowa (np. nagroda wpływa na ekonomię w grze) i opóźnienia w przyznawaniu nagród są dopuszczalne, najlepszym rozwiązaniem może być oczekiwanie na zweryfikowany wywołanie zwrotne po stronie serwera.
Dane niestandardowe
Aplikacje, które wymagają dodatkowych danych w wywołaniach weryfikacji po stronie serwera, powinny korzystać z funkcji niestandardowych danych reklam z nagrodą. Każda wartość ciągu ustawiona w obiekcie reklamy z nagrodą jest przekazywana do parametru zapytania custom_data
wywołania zwrotnego SSV. Jeśli nie ustawisz wartości danych niestandardowych, parametr zapytania custom_data
nie będzie obecny w zwrotnym wywołaniu SSV.
Poniższy przykładowy kod pokazuje, jak ustawić opcje SSV po załadowaniu reklamy z nagrodą.
private void LoadRewardedAd(string adUnitId)
{
// Send the request to load the ad.
AdRequest adRequest = new AdRequest();
RewardedAd.Load(adUnitId, adRequest, (RewardedAd rewardedAd, LoadAdError error) =>
{
// If the operation failed with a reason.
if (error != null)
{
Debug.LogError("Rewarded ad failed to load an ad with error : " + error);
return;
}
var options = new ServerSideVerificationOptions
.Builder()
.SetCustomData("SAMPLE_CUSTOM_DATA_STRING")
.Build()
rewardedAd.SetServerSideVerificationOptions(options);
});
}
Jeśli chcesz ustawić niestandardowy ciąg znaków nagrody, musisz to zrobić przed wyświetleniem reklamy.
Ręczne sprawdzanie reklam z ręcznie przyznawaną nagrodą po stronie serwera
Poniżej opisano czynności wykonywane przez klasę RewardedAdsVerifier
w celu weryfikacji nagradzanego SSV. Chociaż załączone fragmenty kodu są w języku Java i korzystają z biblioteki zewnętrznej Tink, możesz je zaimplementować w dowolnym języku, używając dowolnej biblioteki zewnętrznej obsługującej ECDSA.
Pobieranie kluczy publicznych
Aby zweryfikować wywołanie zwrotne SSV z reklamą z nagrodą, potrzebujesz klucza publicznego udostępnionego przez AdMob.
Listę kluczy publicznych służących do weryfikowania wywołań zwrotnych reklam z nagrodą po stronie serwera można pobrać z serwera kluczy AdMob. Lista kluczy publicznych jest dostarczana w postaci reprezentacji JSON w formacie podobnym do tego:
{
"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=="
},
],
}
Aby pobrać klucze publiczne, połącz się z serwerem kluczy AdMob i pobierz klucze. Poniższy kod wykonuje to zadanie i zapisuje reprezentację kluczy w formacie JSON w zmiennej 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();
}
Pamiętaj, że klucze publiczne są regularnie rotowane. Otrzymasz e-maila z informacją o nadchodzącej rotacji. Jeśli używasz pamięci podręcznej kluczy publicznych, po otrzymaniu tego e-maila zaktualizuj te klucze.
Po pobraniu kluczy publicznych należy je przeanalizować. Metoda parsePublicKeysJson
poniżej przyjmuje jako dane wejściowe ciąg znaków JSON, taki jak przykład powyżej, i tworzy mapowanie wartości key_id
na klucze publiczne, które są opakowane jako obiekty ECPublicKey
z biblioteki 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;
}
Przesyłanie treści do weryfikacji
Ostatnie 2 parametry zapytania w przypadku wywołań zwrotnych SSV z nagrodą to zawsze signature
i key_id,
w tej kolejności. Pozostałe parametry zapytania określają treści, które mają zostać zweryfikowane. Załóżmy, że skonfigurowałeś/skonfigurowałaś AdMob tak, aby wysyłać wywołania zwrotne dotyczące nagrody do adresu https://www.myserver.com/mypath
. Fragment kodu poniżej pokazuje przykład wywołania metody SSV z wyświetlonym treścią, która ma zostać zweryfikowana.
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
Poniższy kod pokazuje, jak zanalizować treści do weryfikacji z adresu URL wywołania zwrotnego jako tablicy bajtów w formacie 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"));
Pobieranie podpisu i klucza_id z adresu URL wywołania zwrotnego
Korzystając z wartości queryString
z poprzedniego kroku, przeanalizuj parametry zapytania signature
i key_id
z adresu URL połączenia zwrotnego, jak pokazano poniżej:
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()));
Przeprowadź weryfikację
Ostatnim krokiem jest zweryfikowanie zawartości adresu URL wywołania zwrotnego za pomocą odpowiedniego klucza publicznego. Użyj mapowania zwróconego przez metodę parsePublicKeysJson
i parametru key_id
z adresu URL wywołania zwrotnego, aby uzyskać klucz publiczny z tego mapowania. Następnie zweryfikuj podpis za pomocą tego klucza publicznego. Te czynności są opisane poniżej w metodach 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);
}
}
Jeśli metoda zostanie wykonana bez wywołania wyjątku, adres URL wywołania zwrotnego został zweryfikowany.
Najczęstsze pytania
- Czy mogę przechowywać w pamięci podręcznej klucz publiczny udostępniony przez serwer kluczy AdMob?
- Zalecamy zapisanie w pamięci podręcznej klucza publicznego udostępnionego przez serwer kluczy AdMob, aby zmniejszyć liczbę operacji wymaganych do sprawdzania wywołań zwrotnych SSV. Pamiętaj jednak, że klucze publiczne są regularnie rotowane i nie powinny być przechowywane w pamięci podręcznej dłużej niż 24 godziny.
- Jak często klucze publiczne udostępniane przez serwer kluczy AdMob są rotowane?
- Klucze publiczne udostępniane przez serwer kluczy AdMob są rotowane zgodnie z zmiennym harmonogramem. Aby mieć pewność, że weryfikacja wywołań zwrotnych SSV działa prawidłowo, nie przechowuj kluczy publicznych w pamięci podręcznej dłużej niż 24 godziny.
- Co się stanie, jeśli nie uda się połączyć z moim serwerem?
- Google oczekuje kodu odpowiedzi o stanie powodzenia
HTTP 200 OK
w przypadku wywołań zwrotnych SSV. Jeśli serwer jest niedostępny lub nie odpowiada zgodnie z oczekiwaniami, Google będzie próbować wysyłać wywołania zwrotne SSV maksymalnie 5 razy w odstępach co 1 sekundę. - Jak mogę sprawdzić, czy wywołania zwrotne SSV pochodzą od Google?
- Aby sprawdzić, czy wywołania zwrotne SSV pochodzą z Google, użyj odwrotnego wyszukiwania DNS.