接入AdMob的奖励视频广告服务端的验证,这里指的用户观看完广告发奖励的通知验证。
进入谷歌的文档说明
文档使用的google自己的库Tink,有必要的可以从仓库找到这个库进行使用。
先说两个字段,这两个是在您的广告那边设置的,item就是你发奖励的商品id
|
reward_amount
|
广告单元设置中指定的奖励金额。
|
5
|
|
reward_item
|
广告单元设置中指定的奖品。
|
金币
|
转到你的广告可以设置
这个就是你前端定义的用户信息
|
custom_data
|
自定义数据字符串,其提供方法为
setCustomData
。
如果应用未提供自定义数据字符串,此查询参数值将不会出现在 SSV 回调中。
|
SAMPLE_CUSTOM_DATA_STRING
|
再前端添加自定义的用户数据
转到您的广告设置服务端验证地址,谷歌是以get的方式请求过来的,比如您的地址是https://xxx/ads/callback
下面进入验证的流程,设置好了地址,当用户观看完广告就会通知你的服务器地址了。谷歌是SHA256withECDSA的验证方式。
1、获取
A
dMob公钥
https://www.gstatic.com/admob/reward/verifier-keys.json
从这个地址获取公钥,公钥列表以 JSON 表示形式提供,我们根据回调参数的key_id寻找对应的公钥,注意这里返回的公钥是base64编码过的,使用的时候需要进行解码
* 获取publicKey
* @param keyId
* @return
public static String getVerifierKeys(final String keyId) {
// {"keys":[{"keyId":3335741209,"pem":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+nzvoGqvDeB9+SzE6igTl7TyK4JB\nbglwir9oTcQta8NuG26ZpZFxt+F2NDk7asTE6/2Yc8i1ATcGIqtuS5hv0Q==\n-----END PUBLIC KEY-----","base64":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+nzvoGqvDeB9+SzE6igTl7TyK4JBbglwir9oTcQta8NuG26ZpZFxt+F2NDk7asTE6/2Yc8i1ATcGIqtuS5hv0Q=="}]}
String publicKey=null;
String result=XHttp.get("https://www.gstatic.com/admob/reward/verifier-keys.json");
System.out.println("result:"+result);
JSONObject json=new JSONObject(result);
JSONArray jsonArray=json.getJSONArray("keys");
for(int i=0;i<jsonArray.length();i++) {
JSONObject jobj=jsonArray.getJSONObject(i);
String key=jobj.optString("keyId");
if(key.equalsIgnoreCase(keyId)) {
publicKey=jobj.getString("base64");
return publicKey;
返回的数据格式如下:
"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=="
2、获取要验证的内容
public static Map<String,Object> getDataToVerify() {
String rewardUrl="http://xxx/ads/callback?ad_network=5450213213286189855&ad_unit=4826801875&custom_data=375759667%2C1%2CroleId&reward_amount=1&reward_item=Rewards×tamp=1590396116896&transaction_id=16855da7c17a63500096b5acca880b9d&signature=MEQCIAvEJKvCRd_7QLKEq6-BvsurUKpppJkQDFzBUe1ZqvO0AiBFRFEJAWAo0Qmaw2FbPDuC62cJD6XhMEPIfiyLkxK4ug&key_id=3335741209";
Map<String,Object> map=new HashMap<String, Object>();
System.out.println("rewardUrl:"+rewardUrl);
String SIGNATURE_PARAM_NAME = "signature=";
URI uri = null;
try {
uri = new URI(rewardUrl);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("===11===");
String queryString = uri.getQuery();
int i = queryString.indexOf(SIGNATURE_PARAM_NAME);
if (i == -1) {
// throw new Exception("needs a signature query parameter");
System.out.println("===22===");
String ystr=queryString
.substring(0, i - 1);
System.out.println("yanz:"+ ystr);
byte[] queryParamContentData =
// i - 1 instead of i because of & in the query string
.getBytes(Charset.forName("UTF-8"));
String KEY_ID_PARAM_NAME = "key_id=";
String sigAndKeyId = queryString.substring(i);
i = sigAndKeyId.indexOf(KEY_ID_PARAM_NAME);
if (i == -1) {
System.out.println("needs a key_id query parameter");
String sig =
sigAndKeyId.substring(
SIGNATURE_PARAM_NAME.length(), i - 1 /* i - 1 instead of i because of & */);
String keyId = sigAndKeyId.substring(i + KEY_ID_PARAM_NAME.length());
System.out.println("sig:"+sig);
System.out.println("keyId:"+keyId);
map.put("queryParamContentData", queryParamContentData);
map.put("keyId", keyId);
try {
map.put("sig",org.apache.commons.codec.binary.Base64.decodeBase64(sig.getBytes("utf-8")) );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
// map.put("sig", Base64.urlSafeDecode(sig));
return map;
rewardUrl就是您的回调地址和谷歌请求过来的参数,获取验证的内容queryParamContentData、keyId、sig
java获取get请求参数和url的方式
StringBuffer url=request.getRequestURL();
url.append("?").append(request.getQueryString());
3、进行验证
* @param data 需要验证的数据
* @param _key public key
* @param sig 谷歌返回的signature参数
* @return
public static boolean verifySign(byte[] data, byte[] _key, byte[] sig) {
try {
java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
_key);
KeyFactory keyf = KeyFactory.getInstance("EC");
PublicKey publicKey = keyf.generatePublic(bobPubKeySpec);
Signature signer = Signature.getInstance("SHA256withECDSA");
signer.initVerify(publicKey);
signer.update(data);
return (signer.verify(sig));
catch(Exception ex)
System.out.println(ex.getMessage());
return false;
Map<String,Object> map=getDataToVerify();
// ecdsaVerifyJce.verify((byte[])map.get("sig"), (byte[])map.get("queryParamContentData"));
String publicKey=getVerifierKeys((String)map.get("keyId"));
boolean isverfy=verifySign((byte[])map.get("queryParamContentData"), org.apache.commons.codec.binary.Base64.decodeBase64(publicKey),(byte[]) map.get("sig"));
System.out.println("isverfy:"+isverfy);
运行不发生异常,且返回true就是验证通过了。
注意:获取的公钥base64的值需要进行base64解码,回调过来的参数signature字段也是需要进行base64解码
接入AdMob的奖励视频广告服务端的验证,这里指的用户观看完广告发奖励的通知验证。进入谷歌的文档说明文档使用的google自己的库Tink,有必要的可以从仓库找到这个库进行使用。先说两个字段,这两个是在您的广告那边设置的,item就是你发奖励的商品idreward_amount 广告单元设置中指定的奖励金额。 5 reward_item 广告单元设置中指定的奖品。 金币 转到你的广告可以设置这个就是你前端定义的用户信息custom_data.
刚开始看官方文档,很容易理解。就是说你自己搭建一个web server,并能接受admob给你规定的参数格式,你根据自己的web server收到的admob给你请求来判定是否给与用户奖励(看完广告)。
理解完以后,顿时觉得很困惑,难道接激励视频广告还得自己架设一台服务器?
官方SDK的回调事件RewardedAd.OnUserEarnedRewa...
Google的激励广告的 Google 回调的服务器端验证 ( SSV ) server side verifiy。Python版本的基于第三方包 ecdsa 开箱即用。
Google公钥的地址:
https://www.gstatic.com/admob/reward/verifier-keys.json
AdMob 密钥服务器提供的公钥会不定期轮换。为确保可以继续按预期验证 SSV 回调,请勿使公钥的缓存时间超过 24 小时。
Google 预计您的服务器会针对 SSV 回调返回
要实现一个Android广告发布系统,您需要考虑以下步骤:
1. 确定广告类型:首先,您需要确定您希望在应用程序中显示哪些类型的广告。这可能包括横幅广告、插页式广告、视频广告、本地广告等。
2. 选择广告平台:您需要选择一个广告平台,如Google AdMob、Facebook Ads或其他广告平台,以便在应用程序中显示广告。这些广告平台提供了SDK和API,使您可以在应用程序中集成广告。
3. 集成广告SDK:您需要将选择的广告平台的SDK集成到应用程序中。此步骤将使您可以在应用程序中显示广告。您可以在广告平台的文档中找到有关如何集成SDK的说明。
4. 创建广告位:在应用程序中显示广告需要创建广告位。您需要确定在应用程序中放置广告的位置和布局,并使用广告平台的工具创建广告位。
5. 加载广告:在创建广告位后,您需要编写代码从广告平台加载广告,并将其显示在应用程序中的广告位中。这可以通过调用广告平台提供的API来实现。
6. 处理广告点击:当用户点击广告时,您需要处理广告点击事件并将用户转到广告网页或其他目标网页。这可以通过使用广告平台提供的回调来实现。
7. 调整广告展示:您可以根据广告的性能对广告展示进行调整。这可能包括更改广告位、调整广告类型、更改广告定位等。
以上是实现Android广告发布系统的基本步骤。您需要对您的应用程序进行适当的测试和优化,以确保广告能够成功地加载和显示,并且对用户和广告主都有良好的体验。