有没有办法验证客户端(OnAdRewarded)是否在服务器上观看了激励视频广告?我可以与 Google Cloud Functions 使用任何集成吗?
我认为可以使用 admob admin SDK 验证客户端发送到服务器的令牌,但似乎不可能,我们只能在客户端验证广告。
有没有办法验证客户端(OnAdRewarded)是否在服务器上观看了激励视频广告?我可以与 Google Cloud Functions 使用任何集成吗?
我认为可以使用 admob admin SDK 验证客户端发送到服务器的令牌,但似乎不可能,我们只能在客户端验证广告。
现在可以使用服务器端验证 (SSV) 回调。
服务器端验证回调是 URL 请求,查询参数由 Google 扩展,由 Google 发送到外部系统,以通知其用户应因与奖励视频广告互动而获得奖励。奖励视频 SSV(服务器端验证)回调提供了额外的保护层,以防止客户端回调的欺骗以奖励用户。
不确定这与 Firebase 是否相关,但如果有人使用 Node / JS,这里有一些详细信息。您可以使用 Node 的内置crypto
库。首先fetch
是来自 的可用 Google AdMob 验证程序密钥https://gstatic.com/admob/reward/verifier-keys.json
。
然后,您需要遍历返回的 JSONkeys
数组并获取与传入字符串pem
的参数对应的公钥文件字符串。req.query.key_id
req.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
库来执行此操作。
现在不行。根据我最近收集的信息,该功能已经处于封闭测试阶段。我能找到的最后一次提及是在链接的讨论中,大概来自 Google 的某个人说该功能将很快向公众推出。该帖子是从1月22日开始的。
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/weXTAGZfYQ8
如果你们正在为 Admob SSV 在 Golang 上寻找一种简单的方法。
只需使用这个hiyali/go-lib-ssv,希望能挽救你的生命 :)
我知道它有点晚了,但这里有一段对我有帮助的代码。它在 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;