4

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

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

4

5 回答 5

6

现在可以使用服务器端验证 (SSV) 回调。

服务器端验证回调是 URL 请求,查询参数由 Google 扩展,由 Google 发送到外部系统,以通知其用户应因与奖励视频广告互动而获得奖励。奖励视频 SSV(服务器端验证)回调提供了额外的保护层,以防止客户端回调的欺骗以奖励用户。

于 2019-04-25T20:42:02.580 回答
2

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

然后,您需要遍历返回的 JSONkeys数组并获取与传入字符串pem的参数对应的公钥文件字符串。req.query.key_idreq.url

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

现在我们可以轻松验证:

   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库来执行此操作。

于 2021-06-21T16:25:37.710 回答
1

现在不行。根据我最近收集的信息,该功能已经处于封闭测试阶段。我能找到的最后一次提及是在链接的讨论中,大概来自 Google 的某个人说该功能将很快向公众推出。该帖子是从1月22日开始的。

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

于 2019-02-20T02:37:25.730 回答
0

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

只需使用这个hiyali/go-lib-ssv,希望能挽救你的生命 :)

于 2019-08-17T05:49:31.033 回答
0

我知道它有点晚了,但这里有一段对我有帮助的代码。它在 JavaScript 中供 Node 用户使用。 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;
于 2021-08-14T23:47:20.050 回答