如何在服务器上验证 Admob 奖励视频广告?

How to verify Admob Rewarded Video Ad on a server?

有没有办法验证服务器上的客户端 (OnAdRewarded) 是否观看了奖励视频广告?我可以与 Google Cloud Functions 进行任何集成吗?

我认为可以使用 admob admin SDK 验证客户端发送到服务器的令牌,但似乎不可能,我们只能在客户端验证广告。

暂时没有。根据我最近收集的信息,该功能已经处于封闭测试阶段一段时间了。我能找到的最后一次提及是在链接的讨论中,据推测来自 Google 的人说该功能将很快推出到 public。 post 是从 1 月 22 日开始的。

https://groups.google.com/forum/#!topic/google-admob-ads-sdk/weXTAGZfYQ8

现在可以使用 Server-Side Verification (SSV) Callbacks.

Server-side verification callbacks are URL requests, with query parameters expanded by Google, that are sent by Google to an external system to notify it that a user should be rewarded for interacting with a rewarded video ad. Rewarded video SSV (server-side verification) callbacks provide an extra layer of protection against spoofing of client-side callbacks to reward users.

如果你们在 Golang 上寻找 Admob SSV 的简单方法。

就用这个hiyali/go-lib-ssv,希望能救你一命:)

不确定这是否与 Firebase 相关,但这里有一些详细信息以防有人使用 Node / JS。您可以使用 Node 的内置 crypto 库。首先 fetch 来自 https://gstatic.com/admob/reward/verifier-keys.json.

的可用 Google AdMob 验证程序密钥

然后您需要遍历返回的 JSON keys 数组并获取与 req.query.key_id 对应的 pem public 密钥文件字符串您传入的 req.url 字符串的参数。

然后我们希望验证签名的“消息”是参数 ? 符号和 &signature... 字符串之间的传入 req.url 子字符串。

现在我们可以轻松验证:

   const verifier = crypto.createVerify("sha256");
   
   verifier.update(message);
   
   if(verifier.verify(pem, req.query.signature, "base64"))
      console.log("Ad was successfully verified.");
   else
      console.log("Ad could not be verified - quick call the cops !");

需要注意的一点是,您可能需要 unescape(...) 您的 req.url 字符串才能使用它,因为某些字符可能已被转义。我坚持了一两个小时。您可以使用例如Node 的内置 querystring 库。

我知道有点晚了,但这里有一段代码对我有帮助。对于 Node 用户,它在 javascript 中。 https://github.com/hypeben/admob-rewarded-ads-ssv

const queryString = require('query-string');
const crypto = require('crypto');
const axios = require('axios');
const GOOGLE_AD_KEY_URL = 'https://gstatic.com/admob/reward/verifier-keys.json';

/**
 * Fetches the google public keys for the admob providers.
 * These keys changes time to time.
 */
 const getGoogleKeysMap = async () => {
 let googleKeyRes = await axios.get(GOOGLE_AD_KEY_URL);
 let {keys} = googleKeyRes.data;
 if (!keys) {
 throw new Error('No keys found from google keys');
 }
 /** For each of the keys array save it base 64 in decoded form in the key map */
 let keyMap = {};
 keys.forEach(k => {
 keyMap[`${k.keyId}`] = crypto.createPublicKey(k.pem);
 console.log(keyMap[`${k.keyId}`]);
 });
 return keyMap;
 };

/**
 * Verifies the callback url query params string,
 * Resolves the promise if verification was successful, else fails.
 * Wanna 'debug' then pass the second parameter as true.
  * @param {String} queryUrl
  * @param {Boolean} debug 
 */
async function verify(queryUrl, debug) {

try {

if (typeof queryUrl !== "string") throw new TypeError("URL needs to be string!");

/**
 * Request coming as callback from admob must contain the 'signature' and the  'user_id'.
 * For more info https://developers.google.com/admob/android/rewarded-video-ssv
 */
const {signature, key_id} = queryString.parse(queryUrl);
if (!signature) {
  throw new Error('No signature value exist in the URL param');
}

if(debug) {
  console.debug('Signature and KeyId ---');
  console.debug(signature, key_id);
//  console.log('Signature and KeyId ---');
//  console.log(signature, key_id);
}

let queryParamsString = queryUrl;
if (queryParamsString.indexOf('?') > -1) {
  queryParamsString = queryUrl.split('?')[1];
}

if(debug) {
  console.debug('Query param string ---');
 // console.log('Query param string ---');
  console.debug(queryParamsString);
 // console.log(queryParamsString);
}

/**
 * As per admob, 
 * The last two query parameters of rewarded video SSV callbacks are always signature and key_id, in that order.
 * The remaining query parameters specify the content to be verified. 
 */
let contentToVerify = queryParamsString.substring(0, queryParamsString.indexOf('signature') -1);

if(debug) {
  console.debug('Content to verify ---');
 // console.log(contentToVerify);
 // console.log('Content to verify ---');
  console.debug(contentToVerify);
}

let keyMap = await getGoogleKeysMap();

if(keyMap[`${key_id}`]) {
  let publicKey = keyMap[`${key_id}`];
  const verifier = crypto.createVerify('RSA-SHA256');
  verifier.update(contentToVerify);
  let result = verifier.verify(publicKey, signature, 'base64');
  if (result) {
    console.debug('Result ---');
     console.debug(result);
    return true;
  } else {
    console.debug('Failure ---');
    console.debug(result);
    throw new Error('Invalid Signature Supplied');
  }
} else {
  console.debug('Key id provided doesn\'t exist ---');
  throw new Error('Key id provided doesn\'t exist in the google public keys');
}


  } catch (error) {

 }

}

module.exports.verify = verify;