«بازخوانهای درستیسنجی سمت سرور» درخواستهای نشانی وب با پارامترهای پُرسمان هستند که Google آنها را ازهم باز میکند و برای سیستم خارجی ارسال میکند تا به آن اطلاع دهد که کاربر باید برای تعامل با آگهی ویدیویی پاداشدار یا آگهی بینابینی پاداشدار پاداش دریافت کند. بازخوانهای «درستیسنجی سمت سرور» پاداشدار لایه محافظتی اضافهای دربرابر جعل بازخوانهای سمت کارخواه برای پاداش دادن به کاربران ارائه میدهند.
این راهنما نحوه درستیسنجی کردن برگشتیهای SSV پاداشدار را بااستفاده از برنامههای جاوا Tink کتابخانه رمزنگاری شخص ثالث نشان میدهد تا مطمئن شوید که پارامترهای پُرسمان در برگشتی مقادیر قانونی هستند. اگرچه از Tink برای اهداف این راهنما استفاده میشود، این گزینه را دارید که از هر کتابخانه طرف سومی که از ECDSA پشتیبانی میکند استفاده کنید. همچنین میتوانید سرورتان را با ابزار آزمایش در واسط کاربر AdMob آزمایش کنید.
پیشنیازها
- درستیسنجی پاداشدار سمت سرور را در واحد آگهیتان فعال کنید.
از RewardedAdsVerifier از کتابخانه Tink Java Apps استفاده کنید
مخزن GitHub برنامههای Tink Java شامل
RewardedAdsVerifier
کلاس کمکی برای کاهش کد موردنیاز برای درستیسنجی کردن برگشتی SSV پاداشدار است.
استفاده از این کلاس به شما امکان میدهد نشانی وب برگشتی را با کد زیر درستیسنجی کنید.
RewardedAdsVerifier verifier = new RewardedAdsVerifier.Builder()
.fetchVerifyingPublicKeysWith(
RewardedAdsVerifier.KEYS_DOWNLOADER_INSTANCE_PROD)
.build();
String rewardUrl = ...;
verifier.verify(rewardUrl);
اگر روش verify() بدون ایجاد استثنا اجرا شود، نشانی وب
پاسخبهتماس باموفقیت درستیسنجی شده است. بخش پاداش دادن به کاربر
روالهای مطلوب را درباره زمان پاداش دادن به کاربران شرح میدهد. برای
جزئیات مراحل انجامشده توسط این کلاس برای درستیسنجی تماسهای برگشتی SSV پاداشدار،
میتوانید بخش درستیسنجی دستی SSV پاداشدار را بخوانید.
پارامترهای فراخوانی SSV
کاربردهای درستیسنجی سمت سرور حاوی پارامترهای پُرسمانی است که تعامل آگهی پاداشدار را توصیف میکند. نامهای پارامتر، شرحها، و مقادیر نمونه در زیر فهرست شده است. پارامترها بهترتیب حروف الفبا ارسال میشوند.
| نام پارامتر | شرح | مقدار نمونه |
|---|---|---|
| ad_network | شناسه منبع آگهی برای منبع آگهی که این آگهی را اجرا کرده است. نامهای منبع آگهی متناظر با مقادیر شناسه در بخش شناسههای منبع آگهی فهرست شدهاند. | 1953547073528090325 |
| ad_unit | شناسه واحد آگهی AdMob که برای درخواست آگهی پاداشدار استفاده شده است. | 2747237135 |
| key_id | کلیدی که برای تأیید تماس برگشتی SSV استفاده میشود. این مقدار به کلید عمومی ارائهشده توسط سرور کلید AdMob نگاشت میشود. | 1234567890 |
| reward_amount | مقدار پاداش همانطور که در تنظیمات واحد آگهی مشخص شده است. | 5 |
| reward_item | مورد پاداش همانطور که در تنظیمات واحد آگهی مشخص شده است. | سکه |
| امضا | امضای تماس برگشتی SSV تولیدشده توسط AdMob. | MEUCIQCLJS_s4ia_sN06HqzeW7Wc3nhZi4RlW3qV0oO-6AIYdQIgGJEh-rzKreO-paNDbSCzWGMtmgJHYYW9k2_icM9LFMY |
| مُهر زمان | مهر زمان زمانی که کاربر پاداش دریافت کرده است بهعنوان زمان Epoch در میلیثانیه. | 1507770365237823 |
| transaction_id | شناسه یکتای کدگذاریشده با هگز برای هر رویداد اعطای پاداش تولیدشده توسط AdMob. | 18fa792de1bca816048293fc71035638 |
| user_id | شناسه کاربر ارائهشده توسط
SetUserId.
اگر شناسه کاربری توسط برنامه ارائه نشود، این پارامتر پُرسمان در فراخوانی SSV وجود نخواهد داشت. |
1234567 |
شناسههای منبع آگهی
نامها و شناسههای منبع آگهی
| نام منبع آگهی | شناسه منبع آگهی |
|---|---|
| تولید آگهی (پیشنهاد قیمت) | 1477265452970951479 |
| شبکه AdMob | 5450213213286189855 |
| آبشار شبکه AdMob | 1215381445328257950 |
| AppLovin | 1063618907739174004 |
| AppLovin (پیشنهاد قیمت) | 1328079684332308356 |
| Bidease (پیشنهاد قیمت) | 3670825090829827805 |
| BidMachine (پیشنهاد قیمت) | 7943972370566394673 |
| Chartboost | 2873236629771172317 |
| Chocolate Platform (مناقصه) | 6432849193975106527 |
| رویداد سفارشی | 18351550913290782395 |
| DT Exchange* * قبلاز ۲۱ سپتامبر ۲۰۲۲، این شبکه «Fyber Marketplace» نامیده میشد. | 2179455223494392917 |
| DT Exchange (پیشنهاد قیمت) | 8189833498765234879 |
| Equativ (پیشنهاد قیمت)* * قبلاز ۱۲ ژانویه ۲۰۲۳، این شبکه «Smart Adserver» نامیده میشد. | 5970199210771591442 |
| نوسان (پیشنهاد قیمت دادن) | 8419777862490735710 |
| i-mobile | 5208827440166355534 |
| بهبود دیجیتال (پیشنهاد قیمت) | 159382223051638006 |
| Index Exchange (پیشنهاد قیمت) | 4100650709078789802 |
| InMobi | 7681903010231960328 |
| InMobi (SDK) (bidding) | 8468954295581492586 |
| InMobi Exchange (پیشنهاد قیمت) | 5264320421916134407 |
| آگهیهای ironSource | 6925240245545091930 |
| آگهیهای ironSource (پیشنهاد قیمت) | 1643326773739866623 |
| درآمدزایی پساز پرتاب* * پیشاز ۳۰ ژانویه ۲۰۲۳، این شبکه «Vungle» نامیده میشد. | 1953547073528090325 |
| Liftoff Monetize (مناقصه)* * قبلاز ۳۰ ژانویه ۲۰۲۳، این شبکه «Vungle (پیشنهاد قیمت)» نامیده میشد. | 4692500501762622185 |
| LY Ads Network | 3025503711505004547 |
| شبکه آگهی LY (پیشنهاد قیمت) | 2615812619460460513 |
| Magnite DV+ (پیشنهاد قیمت) | 3993193775968767067 |
| مه | 7505118203095108657 |
| Media.net (پیشنهاد قیمت) | 2127936450554446159 |
| آگهیهای خانهای واسطهای | 6060308706800320801 |
| Meta Audience Network* * پیشاز ۶ ژوئن ۲۰۲۲، این شبکه «Facebook Audience Network» نام داشت. | 10568273599589928883 |
| شبکه مخاطبان Meta (پیشنهاد قیمت)* * قبلاز ۶ ژوئن ۲۰۲۲، این شبکه «شبکه مخاطبان Facebook (پیشنهاد قیمت)» نامیده میشد. | 11198165126854996598 |
| Mintegral | 1357746574408896200 |
| Mintegral (پیشنهاد قیمت) | 6250601289653372374 |
| Mobfox (پیشنهاد قیمت) | 3086513548163922365 |
| MobileFuse (پیشنهاد قیمت) | 7303547408604090310 |
| کیت توسعه نرمافزار آگهیهای Moloco (پیشنهاد قیمت) | 8267622065755668722 |
| myTarget | 8450873672465271579 |
| بومی (پیشنهاد قیمت دادن) | 3240503836211327896 |
| Nexxen (bidding)* * پیشاز ۱ مه ۲۰۲۴، این شبکه «UnrulyX» نام داشت. | 2831998725945605450 |
| OneTag Exchange (bidding) | 4873891452523427499 |
| OpenX (پیشنهاد قیمت) | 4918705482605678398 |
| Pangle | 4069896914521993236 |
| Pangle KR SDK (bidding) | 12171279046073404914 |
| Pangle ROW SDK (bidding) | 3525379893916449117 |
| Pangle US SDK (bidding) | 15999446638585856012 |
| PubMatic (پیشنهاد قیمت) | 3841544486172445473 |
| PubMatic OpenWrap SDK | 7702975372504485373 |
| کیت توسعه نرمافزار PubMatic OpenWrap (پیشنهاد قیمت) | 1234567890123456789 |
| پویش مدل رزرو | 7068401028668408324 |
| افزایش (پیشنهاد قیمت دادن) | 6816468518946650043 |
| Sharethrough (پیشنهاد قیمت) | 5247944089976324188 |
| Smaato (پیشنهاد قیمت) | 3362360112145450544 |
| Sonobi (پیشنهاد قیمت) | 3270984106996027150 |
| TripleLift (bidding) | 8332676245392738510 |
| Unity Ads | 4970775877303683148 |
| Unity Ads (پیشنهاد قیمت) | 7069338991535737586 |
| گروه Verve (پیشنهاد قیمت) | 5013176581647059185 |
| Vpon | 1940957084538325905 |
| Yieldmo (پیشنهاد قیمت) | 4193081836471107579 |
| YieldOne (پیشنهاد قیمت) | 3154533971590234104 |
| زاکس | 5506531810221735863 |
درحال پاداش دادن به کاربر
هنگام تصمیمگیری درباره زمان پاداش دادن به کاربر، مهم است که بین تجربه کاربری و اعتبارسنجی پاداش تعادل برقرار کنید. کاربرگهای سمت سرور ممکن است قبلاز رسیدن به سیستمهای خارجی با تأخیر مواجه شوند. بنابراین، بهترین روش توصیهشده این است که از فراخوانی برگشتی سمت کارخواه برای پاداش دادن فوری به کاربر استفاده کنید، و درعینحال اعتبارسنجی همه پاداشها را پساز دریافت فراخوانیهای برگشتی سمت سرور انجام دهید. این رویکرد تجربه کاربری خوبی ارائه میدهد و درعینحال اعتبار پاداشهای اعطاشده را تضمین میکند.
بااینحال، برای برنامههایی که اعتبار پاداش در آنها حیاتی است (برای مثال، پاداش بر اقتصاد درونبازی برنامه شما تأثیر میگذارد) و تأخیر در اعطای پاداش قابلقبول است، ممکن است بهترین رویکرد انتظار برای تماس برگشتی سمت سرور تأییدشده باشد.
دادههای سفارشی
برنامههایی که در تماسهای برگشتی درستیسنجی سمت سرور به دادههای اضافی نیاز دارند باید از
ویژگی دادههای سفارشی آگهیهای پاداشدار استفاده کنند. هر مقدار رشتهای که روی یک شیء آگهی پاداشدار تنظیم شده باشد، به پارامتر پُرسمان custom_data در برگشت تماس SSV منتقل میشود. اگر مقدار داده سفارشی تنظیم نشده باشد، مقدار پارامتر پُرسمان custom_data در
بازخوانی SSV وجود نخواهد داشت.
نمونه کد زیر نشان میدهد که چگونه گزینههای SSV را پساز بار شدن آگهی پاداشدار تنظیم کنید:
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);
});
}
اگر میخواهید رشته پاداش سفارشی را تنظیم کنید، باید این کار را قبلاز نمایش آگهی انجام دهید.
درستیسنجی دستی «درستیسنجی سمت سرور» پاداشدار
مراحل انجامشده توسط کلاس RewardedAdsVerifier برای درستیسنجی یک SSV پاداشدار در زیر شرح داده شده است. اگرچه قطعه کدهای گنجاندهشده به زبان Java هستند و از کتابخانه شخص ثالث Tink استفاده میکنند، میتوانید این مراحل را به زبان انتخابی خودتان و بااستفاده از هر کتابخانه شخص ثالثی که از ECDSA پشتیبانی میکند پیادهسازی کنید.
واکشی کلیدهای عمومی
برای درستیسنجی کردن برگشت تماس SSV پاداشدار، به کلید عمومی ارائهشده توسط AdMob نیاز دارید.
فهرست کلیدهای عمومی که برای اعتبارسنجی بازخوانیهای SSV پاداشدار استفاده میشود را میتوان از سرور کلید AdMob واکشی کرد. فهرست کلیدهای عمومی بهصورت نمایش JSON با قالبی مشابه با موارد زیر ارائه میشود:
{
"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=="
},
],
}
برای بازیابی کلیدهای عمومی، به سرور کلید AdMob متصل شوید و کلیدها را بارگیری کنید. کد زیر این کار را انجام میدهد و نمایش JSON کلیدها را در متغیر 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();
}
توجه داشته باشید که کلیدهای عمومی بهطور منظم چرخش میکنند. ایمیلی دریافت خواهید کرد که شما را از چرخش آتی مطلع میکند. اگر کلیدهای عمومی را ذخیره میکنید، باید کلیدها را پساز دریافت این ایمیل بهروز کنید.
وقتی کلیدهای عمومی واکشی شدند، باید تجزیه شوند. روش
parsePublicKeysJson در زیر رشته JSON را، مانند مثال بالا، بهعنوان ورودی میگیرد و نگاشت را از مقادیر key_id به کلیدهای عمومی ایجاد میکند،
که بهعنوان اشیای ECPublicKey از کتابخانه 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;
}
دریافت محتوا برای درستیسنجی
دو پارامتر پُرسمان آخرِ برگشتهای تماس SSV پاداشدار همیشه signature
و key_id, به همین ترتیب هستند. پارامترهای پُرسمان باقیمانده محتوایی را که باید درستیسنجی شود مشخص میکنند. فرض کنیم AdMob را برای ارسال بازخوانیهای پاداش به
https://www.myserver.com/mypath پیکربندی کردهاید. تکه زیر نمونهای از
SSV تماس برگشتی پاداشدار را با محتوای برجستهشده برای درستیسنجی نشان میدهد.
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
کد زیر نشان میدهد که چگونه محتوای موردتأیید را از نشانی وب فراخوان بهعنوان آرایه بایت 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"));
دریافت امضا و key_id از نشانی وب پاسخ تماس
بااستفاده از مقدار queryString از مرحله قبلی، پارامترهای پُرسمان signature و
key_id را از نشانی وب بازگشت تماس تجزیه کنید، همانطور که در زیر نشان داده شده است:
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()));
انجام درستیسنجی
مرحله نهایی درستیسنجی محتوای نشانی وب فراخوانی با کلید عمومی مناسب است. نگاشت برگشتی از روش
parsePublicKeysJson را بگیرید و از پارامتر key_id از نشانی وب
بازخوان برای دریافت کلید عمومی از آن نگاشت استفاده کنید. سپس امضا را با آن کلید عمومی
بهتأیید برسانید. این مراحل در زیر در روش 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);
}
}
اگر روش بدون ایجاد استثنا اجرا شود، نشانی وب فراخوانی با موفقیت درستیسنجی شده است.
پرسشگان
- آیا میتوانم کلید عمومی ارائهشده توسط سرور کلید AdMob را در حافظه نهان ذخیره کنم؟
- توصیه میکنیم کلید عمومی ارائهشده توسط سرور کلید AdMob را ذخیره کنید تا تعداد عملیات لازم برای اعتبارسنجی تماسهای برگشتی SSV کاهش یابد. بااینحال، توجه داشته باشید که کلیدهای عمومی بهطور منظم چرخش میکنند و نباید بیشتر از ۲۴ ساعت ذخیره شوند.
- کلیدهای عمومی ارائهشده توسط سرور کلید AdMob هر چند وقت یکبار چرخش میکنند؟
- کلیدهای عمومی ارائهشده توسط سرور کلید AdMob در یک برنامه زمانی متغیر چرخانده میشوند. برای اطمینان از اینکه درستیسنجی فراخوانیهای SSV همچنان طبق انتظار کار میکند، کلیدهای عمومی نباید بیشتر از ۲۴ ساعت ذخیره موقت شوند.
- اگر سرورم دردسترس نباشد چه اتفاقی میافتد؟
- Google انتظار دارد کد پاسخ وضعیت موفقیت
HTTP 200 OKبرای بازخوانهای SSV دریافت کند. اگر سرورتان دردسترس نباشد یا پاسخ موردانتظار را ارائه ندهد، Google تا پنج بار در فواصل یک ثانیهای برای ارسال فراخوانهای SSV تلاش مجدد خواهد کرد. - چگونه میتوانم درستیسنجی کنم که بازخوانهای SSV از Google میآیند؟
- از جستجوی ساناد معکوس برای تأیید اینکه تماسهای برگشتی SSV از Google منشأ میگیرند استفاده کنید.