AdMob 奖励视频广告服务端验证
接入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、获取 AdMob公钥
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
返回的数据格式如下:
{"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 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 map=new HashMap();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 =ystr// 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 blocke.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 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解码
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
