最近微信小程序代码审核不通过,原因是未将用户的头像和网名做内容接入安全,根据修改指引:
一、什么服务或功能的小程序是UGC小程序?
小程序中的功能或服务中,涉及用户将自己自定义编辑的文字、图片、音频、视频等内容通过小程序进行展示或提供给其他用户的,属于UGC小程序。
二、作为UGC小程序,用户发布的内容与小程序是否相关?
微信小程序的服务提供者应当负有监管责任,应设置过滤违法、违规等不当信息内容的机制,保证用户产生内容符合信息内容的规定。
四、如果UGC小程序平台用户发布以上或其他违规内容,开发者应该怎么做?
1、接入内容安全检测接口:< a href="https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&key=11522142966rk3L2&version=1&lang=zh_CN&platform=2">查看详情 a>
该接口监测接口校验文本/图片是否含有敏感内容,提升信息安全防护能力。
2、目前安全接口支持基础检测能力,建议开发者建立自己的内容审核机制,安排审核团队定期审查小程序运营内容,及时处理违规内容/账户,降低被恶意利用导致传播恶意内容的风险。
通过查阅文档,发现了两种内容安全检测的方式:
根据里面的开发文档,可以很便捷地实现内容安全检测,以下是官方代码:
/**
* 珊瑚图片内容安全
*/
function doImgSecCheck() {
var d = Date.now()
wx.serviceMarket.invokeService({
service: 'wxee446d7507c68b11',
api: 'imgSecCheck',
data: {
"Action": "ImageModeration",
"Scenes": ["PORN", "POLITICS", "TERRORISM", "TEXT"],
"ImageUrl": "http://mat1.gtimg.com/pingjs/ext2020/qqindex2018/dist/img/qq_logo_2x.png",
"ImageBase64": "",
"Config": "",
"Extra": ""
},
}).then(res => {
console.log(res)
})
}
//doImgSecCheck()
/**
* 珊瑚文本内容安全
*/
function doMsgSecCheck () {
wx.serviceMarket.invokeService({
service: 'wxee446d7507c68b11',
api: 'msgSecCheck',
data: {
"Action": "TextApproval",
"Text": "hello world!"
},
}).then(res => {
console.log(res)
})
}
//doMsgSecCheck ()
云调用是小程序·云开发提供的在云函数中调用微信开放接口的能力,需要在云函数中通过
wx-server-sdk
使用。
openapi.security.imgSecCheck
openapi.security.msgSecCheck
需在
config.json
中配置security.imgSecCheck
API 和security.msgSecCheck
API 的权限
找到云函数的config.json文件,在里面添加:
{
"permissions": {
"openapi": [
"security.msgSecCheck",
"security.imgSecCheck"
]
}
}
需要配置云调用权限,每个云函数需要声明其会使用到的接口,否则无法调用,声明的方法是在云函数目录下的 config.json
(如无需新建)配置文件的 permissions.openapi
字段中增加要调用的接口名,permissions.openapi
是个字符串数组字段,值必须为所需调用的服务端接口名称。在每次使用微信开发者工具上传云函数时均会根据配置更新权限,该配置有10分钟的缓存,如果更新后提示没有权限,稍等10分钟后再试。
检查一段文本是否含有违法违规内容。
应用场景举例:
- 用户个人资料违规文字检测;
- 媒体新闻类用户发表文章,评论内容检测;
- 游戏类用户编辑上传的素材(如答题类小游戏用户上传的问题及答案)检测等。 频率限制:单个 appId 调用上限为 4000 次/分钟,2,000,000 次/天。
校验一张图片是否含有违法违规内容。
应用场景举例:
- 图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等;
- 敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。 频率限制:单个 appId 调用上限为 2000 次/分钟,200,000 次/天*(图片大小限制:1M)。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
media | FormData | 是 | 媒体文件数据 |
media 的结构
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
contentType | string | 是 | 数据类型,传入 MIME Type | |
value | Buffer | 是 | 文件 Buffer |
官方代码:
// cloud = require('wx-server-sdk')
// ...
// 方法返回 Promise
cloud.openapi.security.imgSecCheck({
media: {
contentType: 'image/png',
value: Buffer
}
})
这里value的数据类型为Buffer,而我们在小程序端还是云函数端操作图片一般是通过它的文件地址来进行的,后来查阅文档发现:
从云存储空间下载文件
请求参数
字段 | 说明 | 数据类型 | 默认值 | 必填 |
---|---|---|---|---|
fileID | 云文件 ID | String | - | Y |
Promise 返回参数
字段 | 说明 | 数据类型 |
---|---|---|
fileContent | 文件内容 | Buffer |
statusCode | 服务器返回的 HTTP 状态码 | Number |
在这里有我们所需的Buffer数据,所以需要分成两步:先用
const res = await cloud.downloadFile({
fileID: fileID,
})
const buffer = res.fileContent
获取图片文件的buffer,再使用cloud.openapi.security.imgSecCheck()方法检测图片内容是否安全
以下是安全检测云函数的测试代码
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
// 云函数入口函数
exports.main = async (event, context) => {
//文本内容安全
/* try {
let result = await cloud.openapi.security.msgSecCheck({
content: '么么么哒'
})
console.log(result)
if (result.errCode == 0) {
return true;
}
return false
} catch (err) {
return false;
} */
//图片内容安全
const fileID = 'cloud://test-dijf3/test/test.png'
const res = await cloud.downloadFile({
fileID: fileID,
})
const buffer = res.fileContent
try {
var result = await cloud.openapi.security.imgSecCheck({
media: {
contentType:"image/png",
value: buffer
}
})
return result
} catch (err) {
return err
}
}
问题到这里似乎就解决了,但是我要实现的功能是将用户的头像和用户名做安全检测。
在小程序端,使用wx.getUserInfo()可以获得用户的头像链接avatarUrl和用户名nickName,但是这个avatarUrl是一个图片链接,例如:
https://wx.qlogo.cn/mmopen/vi_32********************
点击此链接可以查看用户的头像,但是前面提到的fileID它是在云存储中的一个文件地址,所以需要先把用户头像上传到云存储当中,以便获取fileID。但是要上传到云存储中就必须获得头像图片的临时存储路径filePath,所以要先将图片下载到本地,这里使用wx.getImageInfo(),可以将网络图片保存在本地,从而获取它的临时路径。
wx.getImageInfo({
src: 'https://wx.qlogo.cn/mmopen/vi_32/*************',
success: function (res) { //访问存放微信用户头像的Url
console.log(res.path)
}
})
问题随着而来,系统会提示https://wx.qlogo.cn非downloadFile的合法域名。在详情->项目配置中可以看到:
所以需要在后台->开发->开发设置中设置服务器域名
此时就不会报错了。
然后再上传到云存储中,然后再调用云函数,传入获取的fileID,即可实现。
wx.cloud.uploadFile({
cloudPath:'test.png',
filePath:'',
success: res => {
console.log('[上传文件] 成功:', res)
wx.cloud.callFunction({
name: 'imgSecCheck',
data: {
contentType: contentType,
fileID: res.fileID
}
}).then(res => {
console.log("检测结果", res.result);
})
},
fail: e => {
console.error('[上传文件] 失败:', e)
}
})
步骤如下:
1,通过wx.getImageInfo()将头像图片下载到本地,以获取临时存储路径filePath
2,将头像图片上传到云存储中,以获取fileID
3,通过cloud.downloadFile()获取图片的buffer
4,将buffer填入value,调用cloud.openapi.security.imgSecCheck以实现安全检测
随着学习的深入,我发现可以先将本地图片编码成base64格式,然后直接传入云函数
wx.getFileSystemManager().readFile({
filePath: filePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => { //成功的回调
wx.cloud.callFunction({
name:'imageSecCheck',
data:{
file: res.data
},
success(_res){
console.log(_res)
wx.hideLoading()
//wx.hideLoading()
},fail(_res){
console.log(_res)
}
})
index++;
}
})
云函数端代码:
var buffer = new Buffer(event.file, 'base64')
try {
var result = await cloud.openapi.security.imgSecCheck({
media: {
contentType:"image/png",
value: buffer
}
})
return result
} catch (err) {
return err
}
此时也可以实现图片安全检测,方法更为简洁。
步骤如下:
1,通过wx.getImageInfo()将头像图片下载到本地,以获取临时存储路径filePath
2,将图片数据编码成base64格式,将编码后数据传入云函数
3,通过var buffer = new Buffer(event.file, 'base64')获取图片的buffer
4,将buffer填入value,调用cloud.openapi.security.imgSecCheck以实现安全检测