配置:
- 前端: ng11 + ng-zorro + material + ionic
- 后端: JAVA + py
先说下背景:
目前的活体检测可以大致分为三个类型: - 静默活体
前端传一张或多张照片给后端,后端通过算法模型进行比对,计算出是否是活体,这种活体认证风险较大,易被以假乱真。 - 动作活体
- 前端动作活体:
- 由前端基于webRtc拿到视频流后,利用js算法模型,对视频流中的人脸进行识别、验证,最终检测出是否为活体。(目前我们采用的库是(human),是一个国外大神基于tensorflow开源的算法模型进行封装、改进开发的,有问题可以随时提issue,大神欢迎大家提issue,并尽可能立刻解答。
- 后端动作活体:
- 前端通过网络将资源传输到后端,后端统一处理需要检测的图像或视频流,对后端的架构有一定的挑战,同时网络的延时往往不能给用户带来实时的交互效果。 - 视频活体
- 有两种方案:
1. 前端通过实时发送照片,后端实时进行活体判断,返回检测结果。这种比较耗带宽和后端资源,并且直接发人脸照片数据给后端,容易被劫持,有一定的安全性问题。
2. 前端拍摄一段含有人脸的视频(1~3s),后端拿到之后直接通过算法引擎进行解析,返回是否为活体的结果,这部分是有坑需要去填的,
1. 因为要保证视频在不同平台都能播放,一般要为mp4格式,而通过RecordRTC(webRtc提供的录像接口),是无法直接录制mp4格式的视频的,这就要转格式,后端转格式的话很简单,用ffmpeg这个库就能解决了,而如果要前端来转格式的话,就有些坑了,目前我找到了某佬写的算法,转化之后用pc可以正常播放,但是ios只能播放第一秒,目前还没有解,待后端解了之后会更新解法。
2. 首先webRtc有兼容性问题、其次RecordRtc也有兼容性问题,具体可以查下mdn.
目前,我已经做了基于webRtc的流进行静默活体和动作活体检测(包括摇头、点头、张嘴、眨眼),stream(视频流)在webRtc中是个关键点,如果拿不到stream,所有功能都不可用,因此有些浏览器是用不了我们的活体验证的,于是乎,产品就急了,因为我们项目里刷脸功能大多数是to C的场景,所以,要保证大部分人可以使用刷脸功能。
过程是这样的:
- 产品要把我们原先刷脸登录的H5嵌入到微信公众号里,并能够有效保证,用户的照片是通过现场拍摄上传的,而不是从相册里选择上传。
好了,废话(铺垫)讲得有点多,下面进入正题,调用微信JS-SDJ进行刷脸到底有什么坑? - 首先的大坑在于wx.config在ios中的坑。
- 明明配置相同,android是好的,iOS真机一直报config:invalid signature?
去微信开放社区搜一下就会发现,有很多类似的问题,微信官方也给了解法:
编辑
但是、这种解法根本不奏效,最后一条只说了部分真相,就是不说ios和android在微信里路由渲染的差异。
- 首先要知道wx.config是有限制的,请求签名的页面要和wx-config的页面一模一样,除了hash值,其他的参数都要带上,配置之后其他页面就可以用js-sdk中的方法了,安卓的微信每次跳转路由后,真实页面都会根据路由来刷新。
- 而ios的则不然,当你通过一个页面(index.html)进入微信之后,页面就会被微信打上一个标签,路由再去跳转到其他页面,实际上路由是没有变的,所以这个时候如果再去进行wx.config就会报config:invalid signature,而angular的每一个app,实际上都会被打包成index.html和其他资源文件,微信会基于这个index.html进行打标签,在ios里,每一个app对于wx来说就是一个页面,里面的路由再跳转都是不会刷新的了,所以在angular里需要wx.config的aoo对应的app.compoennt.ts里,需要获取一下当前地址,然后在调微信配置的时候把这个url传过去,再把拿到的配置给wx.config就ok了,里面的module里就都能用了.
编辑
编辑
编辑
我这里目前是写了一个全局service里的变量.
说完ios的坑,下面是andriod的坑.
微信js-sdk拍照提供了一个chooseImage方法,这里可以指定只能用手机摄像头(虽然有兼容性问题),拍完照之后可以拿照片的base64.坑的地方就在这了,ios可以直接通过getLocalImgData方法的返回值,拿localData,就是当前图片的base64,而android拿到的是不标准的base64。没有
data:image/jpeg;base64,所以需要用正则给替换一下
编辑
编辑
export async function imageCutBySrc(image: string, width?: number, height?: number, options?: ImageCutOpt) {
const img = await loadImage(image);
const imgUrl = await imageCutByHTMLImageElement(img, width, height, options);
return imgUrl;
}
/**
* 加载图片
* @param file
*/
export async function loadImage(img: string) {
return new Promise<HTMLImageElement>((resolve, reject) => {
const image = new Image();
image.src = img;
image.onload = () => resolve(image);
image.onerror = function () {
reject();
};
});
}
目前用到的就是这两个方法,其他压缩图片的方法我就不发了(因为我们后端的限制,图片要压缩到100k内才能保证认证速度)
其实还有一个坑是 wx.config里的timesteamp是时间戳时间类型,不能是字符串,如果是字符串会报错.
ps:
最近在做微信相关的东西,遇到了这几个坑,并且有些坑微信是一直没有解决了,比如微信js-sdk的chooseImage方法默认配置打开前置摄像头,这个明明小程序都实现的功能了,就不能加到js-sdk里么,如果有相关开发人员看到了,能帮忙填坑那就是再好不过了~
that's all ,over!