目录
1.前言
2.方案
3.实现
4.小程序端
在之前做的扫码小程序中有个生成二维码功能,对输入的内容没有做敏感信息校验被小程序官方封禁了分享能力。因此需要在小程序输入完内容后需要对其内容做敏感信息校验。
小程序官方给出文本内容安全识别API。
对于官方API有两种实现方案,第一种通过云函数调用(可参考官网信息)。
第二种通过后台程序调用,小程序再调用后台程序。
由于博主正好在腾讯云有云服务,并且现在小程序云环境是收费模式,所以最终决定通过springboot实现的后台调用程序。
获取接口调用凭据 | 微信开放文档 (qq.com)
通过官网API可以看到要做文本内容安全识别需要调用msgSecCheck。
在调用文本识别接口之前先要获取token需要调用getAccessToken。
token获取代码片段
static Long oldTime = 0L;
static String tokenCache = "";
// 过期时间,2h-1m
static Long outTime = 7200000L - 60000;
public @ResponseBody String getToken(){
Long nowTime = System.currentTimeMillis();
Long cacheTime = nowTime - oldTime;
if (oldTime <=0 || cacheTime > outTime){
RestTemplate restTemplate;
restTemplate = new RestTemplate();
String json = restTemplate.getForObject(GET_TOKEN, String.class);
tokenCache = json.split("\"access_token\":\"")[1].split("\",\"")[0].trim();
oldTime = System.currentTimeMillis();
return tokenCache;
}else {
return tokenCache;
}
}
文本安全敏感信息校验源码片段
@ApiOperation("检测文字是否存在违规")
@ApiImplicitParams({
@ApiImplicitParam(name = "content", value = "文字"),
})
@RequestMapping(value = "/checkMsg", method = RequestMethod.POST)
public @ResponseBody boolean check(@RequestParam(value = "content", required = false) String content) throws ExecutionException ,InterruptedException{
String token = getToken();
Map paramMap = new HashMap(1);
paramMap.put("content", content);
Object result = HttpUtil.post("https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + token, JSONUtil.toJsonPrettyStr(paramMap));
JSONObject jsonObject = JSONUtil.parseObj(result);
System.out.println(jsonObject);
boolean flag = false;
//87014 内容含有违法违规内容
int errCode = 87014;
if (jsonObject.getInt("errcode") == errCode) {
flag = true;
}
return flag;
}
完整源码
package com.boot.wxboot.controller;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@Controller
@RequestMapping("/sec")
@Api(tags = "文章检测是否违规")
public class SecurityCheckController {
String APPID = "你的小程序APPID";
String SECRET = "你的小程序SECRET";
String GET_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+SECRET;
static Long oldTime = 0L;
static String tokenCache = "";
// 过期时间,2h-1m
static Long outTime = 7200000L - 60000;
public @ResponseBody String getToken(){
Long nowTime = System.currentTimeMillis();
Long cacheTime = nowTime - oldTime;
if (oldTime <=0 || cacheTime > outTime){
RestTemplate restTemplate;
restTemplate = new RestTemplate();
String json = restTemplate.getForObject(GET_TOKEN, String.class);
tokenCache = json.split("\"access_token\":\"")[1].split("\",\"")[0].trim();
oldTime = System.currentTimeMillis();
return tokenCache;
}else {
return tokenCache;
}
}
@ApiOperation("检测文字是否存在违规")
@ApiImplicitParams({
@ApiImplicitParam(name = "content", value = "文字"),
})
@RequestMapping(value = "/checkMsg", method = RequestMethod.POST)
public @ResponseBody boolean check(@RequestParam(value = "content", required = false) String content) throws ExecutionException ,InterruptedException{
String token = getToken();
Map paramMap = new HashMap(1);
paramMap.put("content", content);
Object result = HttpUtil.post("https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + token, JSONUtil.toJsonPrettyStr(paramMap));
JSONObject jsonObject = JSONUtil.parseObj(result);
System.out.println(jsonObject);
boolean flag = false;
//87014 内容含有违法违规内容
int errCode = 87014;
if (jsonObject.getInt("errcode") == errCode) {
flag = true;
}
return flag;
}
}
由于springboot端没有做json数据格式处理,小程序前端使用application/x-www-form-urlencoded模式请求方式进行后台接口请求。
wx.request({
url: 'https://XXXXXXX/sec/checkMsg', //仅为示例,并非真实的接口地址
header: {
'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
},
data: {
content:txt,
},
method: 'POST',
success(res) {
debugger;
console.log(res.data)
if(res.data){
wx.showToast({ title: "输入内容不规范,请重新输入", icon: "none" });
return ;
}else{
e.makeCode(txt);
}
}
})