赞
踩
uni-sec-check内容安全是unicloud封装了微信小程序的免费接口,文本内容安全识别(msgSecCheck)和音视频内容安全识别(mediaCheckAsync),如果我没选择使用uniapp+unicloud开发的话,可以轻松从插件市场引入uni-sec-check公共模块,完成内容安全检测,包含图片和文字检测,下面就针对文本内容和图片进行安全校验,前置知识肯定需要会uniapp和unicloud等知识。
文本内容安全校验比较容易,只需要将编辑的内容发送给处理函数,接口将立即响应,返回处理结果,经过测试,一般会返回三种类型的敏感提示。
// 引入uni-sec-check公共模块
const UniSecCheck = require('uni-sec-check');
// 初始化实例
const uniSecCheck = new UniSecCheck({
provider: 'mp-weixin',
requestId: this.getUniCloudRequestId(), // 云函数内则写 context.requestId 云对象内则写 this.getUniCloudRequestId()
});
const checkRes = await uniSecCheck.textSecCheck({
content: '', // 文本内容,不可超过500KB
openid: '', // 用户的小程序openid
scene: 2, // 场景值
version: 2, // 接口版本号
});
console.log('checkRes: ', checkRes);
上面代码块是官方的示例,一般官方就给常规的演示,逻辑部分需要自己写,下面是我项目中封装的方法,给大家亮出代码来,也作为一个参考吧。
我将文本安全校验和图片安全校验,全部放到一个云对象中,这样方便统一管理,需要校验文字或者图片,只要调用对应的方法即可,云对象起名为“secCheckContent”。
// 引入uni-sec-check公共模块 const UniSecCheck = require('uni-sec-check'); const db = uniCloud.database(); module.exports = { //文本安全校验方法textSecCheck({文本内容,openid,场景值,接口版本}) async textSecCheck({content,openid="ozBCI62sKO1jZWxxH_nMoZQSYhHo",scene=2,version=2} = {}){ const uniSecCheck = new UniSecCheck({ provider: 'mp-weixin', requestId: this.getUniCloudRequestId(), // 云函数内则写 context.requestId }); const checkRes = await uniSecCheck.textSecCheck({ content, openid, scene, version }) if (checkRes.errCode === 'uni-sec-check-risk-content') { return { code: 400, errMsg: '内容不合规', result: checkRes.result } }else if(checkRes.errCode){ return { code: 400, errMsg: checkRes.errMsg, result: checkRes.result } } return { errCode: 0, errMsg: '' }; }
在客户端调用云对象,引入textSecCheck方法,根据内容返回校验结果。
const secCheckObj = uniCloud.importObject("secCheckContent",{customUI:true});
let sec = await secCheckObj.textSecCheck({content:formData.value.content});
if(sec.errCode != 0){
uni.showModal({
title:sec.errMsg,
content:`输入的内容违规,涉及“${sec.result.label}”,请重新编辑!`,
showCancel:false
})
smtLoading.value = false;
return;
}
以上就是关于文本内容安全的校验,是不是很简单,是不是以为图片校验也很容易,那就大错特错了,图片校验的难度比文本校验的难度高很多。
注意:
为什么说图片校验麻烦,是因为图片接口不能理解将校验结果返回,V2的检测结果是异步返回的,需要提前在微信公众平台「开发」-「开发设置」-「消息推送」开启消息服务,检测结果在 30 分钟内会推送到你的消息接收服务器,以下是全部步骤。
const crypto = require('crypto') function getSignature (token, timestamp, nonce, msgEncrypt) { const str = [token, timestamp, nonce, msgEncrypt].sort().join('') return crypto.createHash('sha1').update(str).digest("hex") } function PKCS7Decode(buf) { let padSize = buf[buf.length - 1] return buf.slice(0, buf.length - padSize) } function decryptMsg (encodingAESKey, msgEncrypt) { const key = Buffer.from(encodingAESKey + '=', 'base64') const iv = key.slice(0, 16) const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv) decipher.setAutoPadding(false) let deciphered = Buffer.concat([decipher.update(msgEncrypt, 'base64'), decipher.final()]) deciphered = PKCS7Decode(deciphered) const content = deciphered.slice(16) const length = content.slice(0, 4).readUInt32BE(0) return { message: JSON.parse(content.slice(4, length + 4).toString()), appId: content.slice(length + 4).toString() } } exports.main = function(event, context) { const { signature: signature, timestamp: timestamp, nonce: nonce, echostr: echostr } = event.queryStringParameters const tmpStr = getSignature('你设置的Token令牌', timestamp, nonce) if (signature === tmpStr) { return echostr } else { return } }
/* imgSecCheck({对象}) *picurls 客户端传url数组来 *openid 用户openid *scene 场景值 *version 版本号 *quanzi_id 业务ID */ async imgSecCheck({picurls,openid="ozBCI62sKO1jZWxxH_nMoZQSYhHo",scene=2,version = 2,quanzi_id}={}){ const uniSecCheck = new UniSecCheck({ provider: 'mp-weixin', requestId: this.getUniCloudRequestId(), // 云函数内则写 context.requestId }); //因为图片校验只能单图验证,所以将客户端传来的url数组循环遍历 for (let image of picurls) { let res = await uniSecCheck.imgSecCheck({ image, openid, scene, version }) //将校验回调的唯一校验码traceId存储图片日志中 await db.collection("sec-check-img-log").add({ quanzi_id, picurl:image, traceId:res.traceId, state:0, publish_date:Date.now() }) } }
let quanzi_id = res.id;
let picurls = formData.value.picurls.map(item=>item.url);
if(picurls.length){
await secCheckObj.imgSecCheck({picurls,quanzi_id});
}
uni.showToast({
title:"发布成功,等待审核",
icon:"none",
mask:true
})
uni.navigateBack();
const crypto = require('crypto'); function getSignature(token, timestamp, nonce, msgEncrypt) { const str = [token, timestamp, nonce, msgEncrypt].sort().join('') return crypto.createHash('sha1').update(str).digest("hex") } function PKCS7Decode(buf) { let padSize = buf[buf.length - 1] return buf.slice(0, buf.length - padSize) } function decryptMsg(encodingAESKey, msgEncrypt) { const key = Buffer.from(encodingAESKey + '=', 'base64') const iv = key.slice(0, 16) const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv) decipher.setAutoPadding(false) let deciphered = Buffer.concat([decipher.update(msgEncrypt, 'base64'), decipher.final()]) deciphered = PKCS7Decode(deciphered) const content = deciphered.slice(16) const length = content.slice(0, 4).readUInt32BE(0) return { message: JSON.parse(content.slice(4, length + 4).toString()), appId: content.slice(length + 4).toString() } } exports.main = async function(event, context) { const db = uniCloud.database(); const { signature: signature, timestamp: timestamp, nonce: nonce, echostr: echostr } = event.queryStringParameters let body = '' if (event.body !== '') { body = JSON.parse(event.body) } let result = body const tmpStr = getSignature('你自己设置的Token', timestamp, nonce) if (signature === tmpStr) { // 验证是从微信发来的消息 if (body.Encrypt) { const decrypt = decryptMsg('微信后台自动生成的秘钥', body.Encrypt); //返回的所有数据 result = decrypt.message //根据图片校验返回的审核ID,比对图片日志表,获取满足条件的数据,作为后续增删改查的依据 let imgLogs = await db.collection("sec-check-img-log").where({traceId:result.trace_id}).get(); let quanzi_id = imgLogs.data[0].quanzi_id; let picurl = imgLogs.data[0].picurl; //【重点】图片合规处理函数 if (result.result.suggest == 'pass') { //根据图片日志返回的quanzi_id获取圈子表中对应指定的数据 let res = await db.collection("soup_quanzi").where({ _id:quanzi_id }).get(); //修改图片状态,下面这段代码要是不想修改图片状态的话可以注释掉 await db.collection("sec-check-img-log").where({traceId:result.trace_id}).update({state:1}); //只用状态为0草稿箱的才能修改圈子状态,1通过的不再修改,-1不通过的也过滤掉 if(res.data[0].quanzi_status==0){ await db.collection("soup_quanzi").where({ _id:quanzi_id }).update({ quanzi_status:1 }); } } //【重点】图片违规的处理函数 if (result.result.suggest == 'risky') { //图片违规,立即将发布的圈子状态改为-1为审核不通过 await db.collection("soup_quanzi").where({ _id:quanzi_id }).update({ quanzi_status:-1 }); //将图片日志的状态改为-1为不通过 await db.collection("sec-check-img-log").where({traceId:result.trace_id}).update({state:-1}); //删除违规图片,如果要看看用户传了什么,可以不删,但是占用存储空间,看个人选择,可以注释掉 await uniCloud.deleteFile({fileList: [picurl]}) } } return 'success' } else { return 'success' } }
图片校验完整的消息推送回调,下面代码给大家展示出来,分别是没有问题的图和违规图的返回值。
图片没有问题的返回值
{ "result": { "ToUserName": "gh_ba616cbd6", "FromUserName": "ozBCI62MZ0HWGNeZ2ce7lSWq8", "CreateTime": 1695657534, "MsgType": "event", "Event": "wxa_media_check", "appid": "wxbd9d0a676b6a4", "trace_id": "651ae3a-5d4d44c-0f9e49e", "version": 2, "detail": [ { "strategy": "content_model", "errcode": 0, "suggest": "pass", "label": 100, "prob": 90 } ], "errcode": 0, "errmsg": "ok", "result": { "suggest": "pass", "label": 100 } } }
违规图的回调
{ "result": { "ToUserName": "gh_4dbf781cf1", "FromUserName": "o7ZWr5bHxZ0yMEt6-k_8RUU", "CreateTime": 1693843523, "MsgType": "event", "Event": "wxa_media_check", "appid": "wx3f7cf3d3a423a", "trace_id": "64f603b-4a8bf26-05c372e", "version": 2, "detail": [ { "strategy": "content_model", "errcode": 0, "suggest": "risky", "label": 20002, "prob": 90 } ], "errcode": 0, "errmsg": "ok", "result": { "suggest": "risky", "label": 20002 } } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。