From d7b0a3337b68216d0c311a90d04ab27e7ec76753 Mon Sep 17 00:00:00 2001 From: handongxun Date: Mon, 16 May 2022 14:49:23 +0800 Subject: [PATCH] =?UTF-8?q?rewardedVideoAd:=20=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E5=8F=8A=E5=AE=89=E5=85=A8=E4=BA=8B=E9=A1=B9?= =?UTF-8?q?=E7=A7=BB=E8=87=B3=E6=96=B0=E7=9A=84=E7=BB=84=E4=BB=B6=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api/a-d/rewarded-video.md | 189 +-------------------------------- 1 file changed, 3 insertions(+), 186 deletions(-) diff --git a/docs/api/a-d/rewarded-video.md b/docs/api/a-d/rewarded-video.md index f800eefa1..576149c50 100644 --- a/docs/api/a-d/rewarded-video.md +++ b/docs/api/a-d/rewarded-video.md @@ -556,197 +556,14 @@ rewardedVideoAd.onClose(e => { }) ``` -### 服务器回调说明 - -服务器回调基于[uniCloud](https://uniapp.dcloud.net.cn/uniCloud/README),详细流程如下: - -1. 登陆 [uniCloud](https://unicloud.dcloud.net.cn/) web控制台,新建服务空间或选择已有服务空间,然后在HBuilderX中新建uni-app项目并关联服务空间,新建云函数上传,用于接收广告的回调 -2. 在 [uniAD](https://uniad.dcloud.net.cn/) web控制台开通服务器回调并选择上一步新建的云函数 -3. 开通后将在选择的服务空间下自动部署一个加密云函数 `uniAdCallback` -4. `uniAdCallback` 接收广告商服务器回调验证签名并抹平穿山甲/优量汇/快手参数差异,然后以 [callFunction](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=callbyfunction) 方式调用用户云函数 -5. 用户在自己的云函数中处理业务 - -注意: -1. 服务器通信和前端事件是并行的,前端需要轮询向服务器请求并验证结果 -2. 不建议在 `uniAD` web控制修改回调的服务空间和云函数名称,因为修改后生效需要一段时间 - -### Q&A - -Q: 回调为什么使用[uniCloud](https://uniapp.dcloud.net.cn/uniCloud/README),而不是直接配置开发者的服务器 -A: -1. 由于多家广告商的回调和签名验证逻辑不同,开发者需要写很多逻辑,`uniCloud` 中的云函数 `uniAdCallback` 已抹平了差异,开发者按照统一的参数处理即可 -2. 开发者的服务器有可能响应慢或失去响应造成回调数据丢失, 使用 `uniCloud` 可以帮助开发者保存一份来自广告商服务器的回调数据到开发者的云数据中,以便开发者主动查询 -3. `uniCloud` 可以承载大并发、防DDoS攻击,无需运营人员维护,如果选择了 `阿里云` 且是免费的 - -### 云函数uniAdCallback传递的参数 - -|字段定义|类型|字段名称|备注| -|:-:|:-:|:-:|:-:| -|adpid|String|DCloud广告位id|| -|provider|String|广告服务商|csj、ks、gdt、sigmob| -|platform|String|平台|iOS、Android| -|trans_id|String|交易id|完成观看的唯一交易ID| -|user_id|String|用户id|调用SDK透传,应用对用户的唯一标识| -|extra|String|自定义数据|调用SDK传入并透传,如无需要则为空| - - -#### 用户的云函数返回数据约定 - -返回json数据,字段如下: - -字段名称|说明|字段类型|备注| -:-|:-|:-|:-| -isValid|校验结果|Blean|判定结果,是否发放奖励| - -示例 -```js -exports.main = async (event, context) => { - //event为客户端上传的参数 - console.log('event : ', event); - - return { - "isValid": true - } -}; -``` - -#### 用户云函数详细说明 - -如果业务使用了uniCloud,可以直接在云函数内部处理 - -也可以将结果发送给已有业务服务器 - -示例代码 -```js -'use strict'; - -const crypto = require('crypto'); - -const db = uniCloud.database(); - -const DEFAUTL_TIMEOUT = 30000; -const DEFAUTL_RETRY_COUNT = 3; -const RETRY_TIMEOUT = 3000; - -const ProviderType = { - CSJ: "csj", - GDT: "gdt", - KS: "ks" -}; - -const collectionName = "opendb-uniad-callback-log"; - -class DB { - - static save(data) { - return new DB().add(data); - } - - add(data) { - const collection = db.collection(collectionName); - const data2 = Object.assign(data, { - ad_type: 0, - create_date: new Date() - }) - return collection.add(data2); - } -} - -class UserServer { - - static send(url, data) { - return new UserServer().sendHttpRequest(url, data); - } - - async sendHttpRequest(url, data) { - let needRetry = data.provider !== ProviderType.GDT; - let retryCount = needRetry ? DEFAUTL_RETRY_COUNT : 1; - let timeout = needRetry ? RETRY_TIMEOUT : DEFAUTL_TIMEOUT; - let result = null; - - while (retryCount > 0) { - console.log("sendHttpRequest::count::" + retryCount + "::", url, data); - - try { - result = await uniCloud.httpclient.request(url, { - data, - dataType: 'json', - contentType: 'json', - timeout - }); - - if (result.data && result.data.isValid === true) { - break; - } - } catch (e) { - console.log(e); - } - - retryCount--; - } - - return result; - } -} - -exports.main = async (event, context) => { - //event为客户端上传的参数 - console.log('event : ', event); - - const { - path, - queryStringParameters - } = event; - - const data = { - adpid: event.adpid, - platform: event.platform, - provider: event.provider, - trans_id: event.trans_id, - sign: event.sign, - user_id: event.user_id, - extra: event.extra, - } - - // 注意::必须验签请求来源 - const secret = "";// uniad 后台开通激励视频回调后生成的 Security key - const trans_id = event.trans_id; - const sign2 = crypto.createHash('sha256').update(`${secret}:${trans_id}`).digest('hex'); - if (event.sign !== sign2) { - return null; - } - - - // 可选将回调记录保存到uniCloud,避免用户服务器没有响应时有日志可查,如果选择了保存记录需要做定时清理日志,避免日志过多影响性能 - // try { - // await DB.save(data); - // } catch (e) { - // console.log(e); - // } - - //const url = "https://"; // 用户业务服务器地址,为了避免请求被伪造,必须使用签名的方式请求 - //let reuslt = await UserServer.send(url, data); - - return reuslt -}; -``` +### 服务器回调 +[服务器回调详细说明](https://uniapp.dcloud.net.cn/component/ad-rewarded-video.html#callback) #### 安全注意 -由于激励视频对应着用户奖励,可能会遇到恶意刷激励奖励但实际上并不看广告的情况。此时广告平台不给结算,但开发者却可能把激励送出去。 - -为了提升安全性,建议所有使用激励视频的开发者都要做如下工作来加强保护: -1. 前端代码加密。涉及激励相关的,在manifest中配置好要加密的代码文件,打包后会自动加密相应文件。[详见](https://ask.dcloud.net.cn/article/36437) -2. apk加固。即便前端代码加密,原生层引擎的java代码仍然可能被反编译,需要对apk加固。市面上很多加固服务,比如360加固、爱加密加固均可以自行选择。 -3. 使用如下安全类API,防止客户端被篡改 -- plus.navigator.getSignature 获取应用签名标识。结合在服务器端存放证书信息,可比对判断App的证书是否被重签 [规范](https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.getSignature) -- plus.navigator.isSimulator 判断App是否运行在模拟器环境 [规范](https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.isSimulator) -- plus.navigator.isRoot 判断设备是否被root或越狱 [规范](https://www.html5plus.org/doc/zh_cn/navigator.html#plus.navigator.isRoot) -- plus.networkinfo.isSetProxy 判断设备的网络是否设置了代理 [规范](https://www.html5plus.org/doc/zh_cn/device.html#plus.networkinfo.isSetProxy) -4. 避免使用短信验证码来识别身份,推荐使用可信度更高的 [手机号一键登录](/univerify) 或 [微信登录](/api/plugins/login?id=login) -5. 必要时可使用[生物认证(指纹和faceid)](/api/system/authentication)、[活体检测的sdk](https://ext.dcloud.net.cn/search?q=%E6%B4%BB%E4%BD%93%E6%A3%80%E6%B5%8B&orderBy=Relevance&cat1=5&cat2=51) +[详细说明](https://uniapp.dcloud.net.cn/component/ad-rewarded-video.html#%E5%AE%89%E5%85%A8%E6%B3%A8%E6%84%8F) #### 获取广告商名称 -- GitLab