Wywołania zwrotne weryfikacji po stronie serwera to żądania adresów URL z parametrami zapytania rozszerzone przez Google, które są wysyłane przez Google do systemu zewnętrznego w celu powiadomić go, że użytkownik powinien być nagrodzony za interakcję z reklama pełnoekranowa z nagrodą. Wywołania zwrotne SSV (weryfikacja po stronie serwera) zapewniają dodatkową warstwę ochrony przed podszywaniem się w wywołaniach zwrotnych po stronie klienta; aby nagradzać użytkowników.
Z tego przewodnika dowiesz się, jak zweryfikować wywołania zwrotne SSV z nagrodą za pomocą Aplikacje w Javie Tink innych firm biblioteki kryptograficznej, by zapewnić, że parametry zapytania w wywołaniu zwrotnym będą prawidłowe wartości. Chociaż w tym przewodniku Tink jest używany, możesz korzystać z biblioteki innej firmy, która obsługuje ECDSA Serwer możesz też przetestować za pomocą testowania w interfejsie AdMob.
Zobacz w pełni działającą przykład za pomocą Sprężynowego rozruchu Java.
Wymagania wstępne
Dodaj reklamy z nagrodą do aplikacja mobilna z pakietu SDK do reklam mobilnych Google w wersji 11.6.0 lub nowszej.
Włącz reklamę z nagrodą po stronie serwera weryfikację jednostki reklamowej.
Korzystanie z narzędzia NagrodyAdsVerifier z biblioteki aplikacji Tink w języku Java
repozytorium Tink Java Apps na GitHubie.
zawiera
RewardedAdsVerifier
.
klasy pomocniczej, aby zmniejszyć kod wymagany do weryfikacji wywołania zwrotnego SSV z nagrodą.
Użycie tej klasy umożliwia zweryfikowanie adresu URL wywołania zwrotnego za pomocą poniższego 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 zgłaszania wyjątku, wywołanie zwrotne
Adres URL został zweryfikowany. Pole Nagradzanie użytkowników
zawiera szczegółowe informacje o sprawdzonych metodach dotyczących tego, kiedy użytkownicy powinni otrzymywać nagrody. Dla
zestawienie czynności wykonywanych przez tę klasę w celu weryfikacji wywołań zwrotnych SSV z nagrodą
przeczytaj artykuł Ręczna weryfikacja reklam z nagrodą
SSV.
Parametry wywołania zwrotnego SSV
Wywołania zwrotne weryfikacji po stronie serwera zawierają parametry zapytania opisujące interakcji z reklamą z nagrodą. Nazwy parametrów, opisy i przykładowe wartości to wymienionych 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 wyświetliło tę reklamę. Źródło reklam nazwy odpowiadające wartościom identyfikatora są wymienione na liście identyfikatory źródeł. | 1953547073528090325 |
ad_unit | Identyfikator jednostki reklamowej AdMob użytej do wysłania żądania reklamy z nagrodą. | 2747237135 |
custom_data | Niestandardowy ciąg danych dostarczony przez
setCustomData
.
Jeśli aplikacja nie podaje niestandardowego ciągu danych, ten parametr zapytania nie zostanie podana w wywołaniu zwrotnym SSV. |
SAMPLE_CUSTOM_DATA_STRING |
key_id | Klucz używany do weryfikacji wywołania zwrotnego SSV. Ta wartość jest mapowana na klucz publiczny dostarcza serwer kluczy AdMob. | 1234567890 |
reward_amount | Kwota nagrody określona w ustawieniach jednostki reklamowej. | 5 |
reward_item | Przedmiot nagrody zgodnie z ustawieniami 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 milisekundach) przyznania użytkownikowi nagrody w postaci czasu epoki. | 1507770365237823 |
transaction_id | Unikalny, zakodowany szesnastkowo identyfikator każdego zdarzenia przyznania nagrody wygenerowanego przez AdMob. | 18fa792de1bca816048293fc71035638 |
user_id | Identyfikator użytkownika podany przez
setUserId
Jeśli aplikacja nie podaje identyfikatora użytkownika, ten parametr zapytania nie będzie 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 reklam |
---|---|
Aarki (określanie stawek) | 5240798063227064260 |
Generowanie reklam (ustalanie stawek) | 1477265452970951479 |
AdColony | 15586990674969969776 |
AdColony (poza pakietem 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 |
Platforma czekolady (określanie stawek) | 6432849193975106527 |
Wiele kanałów (MdotM) | 9372067028804390441 |
Zdarzenie niestandardowe | 18351550913290782395 |
DT Exchange* * Przed 21 września 2022 r. sieć nosiła nazwę „Fyber Marketplace”. | 2179455223494392917 |
EMX (określanie stawek) | 8497809869790333482 |
Zmienność (ustalanie stawek) | 8419777862490735710 |
Lekkie | 3376427960656545613 |
Fyber* * To źródło reklam służy do raportowania historycznego. | 4839637394546996422 |
i-mobile | 5208827440166355534 |
Ulepszaj reklamy cyfrowe (ustalanie stawek) | 159382223051638006 |
Index Exchange (ustalanie stawek) | 4100650709078789802 |
InMobi | 7681903010231960328 |
InMobi (określanie stawek) | 6325663098072678541 |
Giełda InMobi (określanie stawek) | 5264320421916134407 |
IronSource | 6925240245545091930 |
Reklamy ironSource (ustalanie stawek) | 1643326773739866623 |
Leadbolt | 2899150749497968595 |
LG U+AD | 18298738678491729107 |
Sieć reklamowa LINE | 3025503711505004547 |
Maio | 7505118203095108657 |
maio (określanie stawek) | 1343336733822567166 |
Media.net (określanie stawek) | 2127936450554446159 |
Zapośredniczone autoreklamy | 6060308706800320801 |
Meta Audience Network* * Przed 6 czerwca 2022 r. sieć nosiła nazwę „Facebook Audience Network”. | 10568273599589928883 |
Meta Audience Network (określanie stawek)* * Przed 6 czerwca 2022 r. sieć nosiła nazwę „Facebook Audience Network (określanie stawek)”. | 11198165126854996598 |
Mintegral | 1357746574408896200 |
Mintegral (określanie stawek) | 6250601289653372374 |
MobFox | 8079529624516381459 |
MobFox (określanie stawek) | 3086513548163922365 |
MoPub (wycofane) | 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 |
Planeta SK | 734341340207269415 |
Współczynnik udziału (określanie stawek) | 5247944089976324188 |
Smaato (określanie stawek) | 3362360112145450544 |
Równy (określanie stawek)* * Do 12 stycznia 2023 r. sieć ta nazywała się „Smart Adserver”. | 5970199210771591442 |
Sonobi (określanie stawek) | 3270984106996027150 |
Tapjoy | 7295217276740746030 |
Tapjoy (określanie stawek) | 4692500501762622178 |
Tencent (GDT) | 7007906637038700218 |
TripleLift (określanie stawek) | 8332676245392738510 |
Reklamy Unity | 4970775877303683148 |
Reklamy Unity (określanie stawek) | 7069338991535737586 |
Verizon Media, | 7360851262951344112 |
Grupa Verve (określanie stawek) | 5013176581647059185 |
Vpon | 1940957084538325905 |
Liftoff – zarabianie* * Przed 30 stycznia 2023 r. sieć ta nazywała się „Vungle”. | 1953547073528090325 |
Liftoff Monetize (określanie stawek)* * Przed 30 stycznia 2023 r. sieć ta nosiła nazwę „Vungle (określanie stawek)”. | 4692500501762622185 |
Yieldmo (określanie stawek) | 4193081836471107579 |
YieldOne (określanie stawek) | 3154533971590234104 |
Kaczki | 5506531810221735863 |
Nagradzanie użytkownika
Ważne jest zachowanie równowagi między wygodą użytkowników a weryfikacją nagród i określić, kiedy należy nagradzać użytkownika. W przypadku wywołań zwrotnych po stronie serwera mogą wystąpić opóźnienia przed które docierają do systemów zewnętrznych. Dlatego zalecamy stosowanie wywołanie zwrotne po stronie klienta, by natychmiast nagrodzić użytkownika, weryfikacji wszystkich nagród po otrzymaniu wywołań zwrotnych po stronie serwera. Ten zapewnia wygodę użytkownikom, a jednocześnie zapewnienie prawidłowości nagrody.
Jednak w aplikacjach, w których ważność nagrody jest kluczowa (na przykład wpływa na ekonomię w grze), a opóźnienia w ich przyznawaniu są akceptowalne, najlepszym rozwiązaniem jest oczekiwanie na zweryfikowane wywołanie zwrotne po stronie serwera. jak ważna jest pokora.
Dane niestandardowe
W przypadku aplikacji, które wymagają dodatkowych danych w wywołaniach zwrotnych weryfikacji po stronie serwera, należy użyć parametru
niestandardowe dane reklam z nagrodą. Dowolny ciąg znaków ustawiony w reklamie z nagrodą
jest przekazywany do parametru zapytania custom_data
w wywołaniu zwrotnym SSV. Jeśli nie
niestandardowych wartości danych, wartość parametru zapytania custom_data
nie będzie
w wywołaniu zwrotnym SSV.
Poniższy przykładowy kod pokazuje, jak ustawić opcje SSV po tagu reklama z nagrodą została wczytana.
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 } })
Jeśli chcesz ustawić niestandardowy ciąg nagrody, musisz to zrobić przed wyświetleniem reklamę.
Ręczna weryfikacja reklamy SSV z nagrodą
Czynności wykonywane przez klasę RewardedAdsVerifier
w celu zweryfikowania reklamy z nagrodą
Poniżej znajdziesz opis usługi SSV. Mimo że dołączone fragmenty kodu są w języku Java
jeśli korzystasz z biblioteki zewnętrznej Tink, możesz wykonać te czynności
w wybranym języku, używając do tego dowolnej biblioteki zewnętrznej, która obsługuje
ECDSA
Pobierz klucze publiczne
Aby zweryfikować wywołanie zwrotne SSV z nagrodą, potrzebujesz klucza publicznego dostarczonego przez AdMob.
Lista kluczy publicznych używanych do weryfikacji wywołań zwrotnych SSV z nagrodą może być pobrane z klucza AdMob Lista kluczy publicznych jest podana 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 plik
klawiszy. Następujący kod wykonuje to zadanie i zapisuje JSON
reprezentacja kluczy do 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 poddawane rotacji. Otrzymasz e-maila z informacjami o nadchodzącej rotacji. Jeśli buforujesz klucze publiczne, musisz zaktualizować klucze.
Po pobraniu kluczy publicznych należy je przeanalizować.
Poniższa metoda parsePublicKeysJson
pobiera ciąg znaków JSON, jak w przykładzie.
powyżej jako danych wejściowych i tworzy mapowanie z wartości key_id
na klucze publiczne,
zapakowane 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;
}
Pobieranie treści do zweryfikowania
Ostatnie 2 parametry zapytania wywołań zwrotnych SSV z nagrodą mają zawsze wartość signature
i key_id,
w tej kolejności. Pozostałe parametry zapytania określają treść
do weryfikacji. Załóżmy, że skonfigurujesz w AdMob wysyłanie wywołań zwrotnych do nagrody
https://www.myserver.com/mypath
Fragment kodu poniżej zawiera przykład reklamy z nagrodą
Wywołanie zwrotne SSV z wyróżnioną treścią do zweryfikowania.
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 przeanalizować treść, która ma zostać zweryfikowana adresu URL wywołania zwrotnego jako tablicy 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 identyfikatora key_id z adresu URL wywołania zwrotnego
Korzystając z wartości queryString
z poprzedniego kroku, przeanalizuj analizy signature
i
Parametry zapytania key_id
z adresu URL wywołania 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 weryfikacja treści adresu URL wywołania zwrotnego za pomocą atrybutu
odpowiedni klucz publiczny. Użyj mapowania zwróconego z
metody parsePublicKeysJson
i użyj parametru key_id
z wywołania zwrotnego
Adres URL do pobrania klucza publicznego z tego mapowania. Następnie zweryfikuj podpis, używając
taki klucz publiczny. Kroki te zostały opisane poniżej w metodzie 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 jest wykonywana bez zgłaszania wyjątku, adres URL wywołania zwrotnego miał postać zweryfikowano.
Najczęstsze pytania
- Czy mogę zapisać w pamięci podręcznej klucz publiczny udostępniony przez serwer kluczy AdMob?
- Zalecamy zapisywanie w pamięci podręcznej klucza publicznego dostarczonego przez klucz AdMob serwera, aby zmniejszyć liczbę operacji wymaganych do weryfikacji SSV . Pamiętaj jednak, że klucze publiczne są regularnie poddawane rotacji i nie należy ich mogą być przechowywane w pamięci podręcznej dłużej niż 24 godziny.
- Jak często poddawana jest rotacja kluczy publicznych dostarczanych przez serwer kluczy AdMob?
- Klucze publiczne przekazane przez serwer kluczy AdMob są poddawane rotacji na zmiennej harmonogram. Aby weryfikacja wywołań zwrotnych SSV nadal działała kluczy publicznych nie należy przechowywać w pamięci podręcznej dłużej niż przez 24 godziny.
- Co się stanie, jeśli mój serwer będzie nieosiągalny?
- Google oczekuje kodu odpowiedzi stanu powodzenia
HTTP 200 OK
w przypadku SSV . Jeśli serwer jest nieosiągalny lub nie zapewnia , Google spróbuje ponownie wysłać wywołania zwrotne SSV maksymalnie 5 razy jednosekundowych odstępach. - Jak sprawdzić, czy wywołania zwrotne SSV pochodzą z Google?
- Użyj wstecznego wyszukiwania DNS, by sprawdzić, czy wywołania zwrotne SSV pochodzą z Google.