微信小程序 人脸识别登陆模块
微信小程序---人脸识别登陆的实现
关键词:微信小程序 人脸识别 百度云接口
前言
这是一篇关于一个原创微信小程序开发过程的原创文章。涉及到的核心技术是微信小程序开发方法和百度云人脸识别接口。小程序的主体是一个用于个人密码存储的密码管理器,在登陆注册阶段,需要调用百度云人脸识别接口以及百度云在线人脸库的管理接口。本文主要涉及登陆注册模块的实现,而且不需要PHP后台代码,完全在线调用接口实现,希望后来的你能有所收获!【自己玩玩可以,如果要实际生产使用,慎重!!!】
注:之前存在的1.移动端无法使用(请打开手机调试功能,具体操作在文末);2.注册和登录需要多次尝试才能成功;3.小问题报错 问题,均已解决,目前可以正常使用。(这里要感谢@lllsp童鞋发现问题,并提出解决方法)
步骤
步骤 | 涉及接口(百度云) |
拍摄或者相册选择 并 上传比对样本照片到 人脸库 | 人脸库管理接口(main:人脸注册) |
拍摄照片并上传,云服务器在线比对 人脸库照片与上传图片的相似度 | 人脸识别接口 |
获取返回结果(相似度) | 人脸识别接口 |
开发过程
1.拍摄人脸图片上传至人脸库---注册
准备工作:需要在百度云注册(或者直接用百度云盘app扫码登陆),并创建人脸识别的应用。(完全免费)
具体如下:
注册完成后(或者直接扫码登陆),进入管理控制台->产品服务->人工智能->人脸识别->创建应用->填写必要信息->立即创建
至此,我们已经创建好了人脸识别的应用。接下来,进入应用列表,找到我们才新建的应用,查看人脸库,我们需要创建用户组(用来集中管理小程序的用户人脸照片)
新建组(id不要太复杂,后面还要用的。)
至此,我们已经完成了在云上的所有必要操作。下面,我们在小程序中,拍照上传即可。
拍照上传
需要在pages中新建一个目录,用来承载我们的登陆注册模块。就假定为 camera{camera.js camera.wxml camera.wxss camera.json}
主要文件自然是 *.wxml 和 *.js 了。
camera.wxml
- <!-- camera.wxml相机大小需要从重新设置 -->
- <camera
- device-position="front"
- flash="off"
- binderror="error"
- style="width: 100%; height: 400px;"
- ></camera>
- <!-- 需要使用 button 来授权登录 -->
- <button
- wx:if="{{canIUse}}"
- open-type="getUserInfo"
- bindgetuserinfo="bindGetUserInfo"
- type="primary"
- >
- 授权
- </button>
- <view wx:else>请升级微信版本</view>
- <!-- 拍照按钮 -->
- <button type="primary" bindtap="takePhoto"> 拍照 </button>
- <button bindtap='btnreg'> 注册须知 </button>
我所谓的授权是,我需要获取用户微信的昵称来充当我人脸库照片的用户id,你可以不需要(设置成一样的,如果是只有一个人使用的话。)
camera.js
调用wxAPI takePhoto() 拍照并获取src -> wx.request() 访问百度云 用先前创建的应用的API Key & Screct Key 获取 access_token -> wx.request() 访问百度云 上传 所拍照片(要经过base64编码)详情可参考小程序API文档 以及 百度云API文档(接口已经于18年升级至v3)
- // camera.js
- const app = getApp()
- Page({
- data: {
- canIUse: wx.canIUse('button.open-type.getUserInfo'),
- nickName: "",
- src: "", //图片的链接
- token: "",
- base64: "",
- msg: ""
- },
- //拍照后调用的函数,用于获取token和上传图片进行注册
- myrquest: function () {
- var that = this;
- wx.request({
- url: 'https://aip.baidubce.com/oauth/2.0/token',
- data: {
- grant_type: 'client_credentials',
- client_id: '***************',//自己的API key
- client_secret: '******************' //自己的密码
- },
- header: {
- 'Content-Type': 'application/json' // 默认值
- },
- success(res) {
- that.setData({
- token: res.data.access_token //获取到token
- }) //上传人脸进行注册
- wx.request({
- url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=' + that.data.token,
- method: 'POST',
- data: {
- image: that.data.base64,
- image_type: 'BASE64',
- group_id: '**********', //自己的组id
- user_id: that.data.nickName //这里获取
- },
- header: {
- 'Content-Type': 'application/json' // 默认值
- },
- success(res) { var errorcode = res.data.error_code
- //做成功判断
- if (errorcode == 0) {
- wx.showToast({
- title: '注册成功',
- icon: 'success',
- duration: 500
- })
- //注册成功,跳转到主界面
- wx.switchTab({
- url: '../UI/ui'
- })
- }
- }
- })
- }
- })
- },
- //拍照
- takePhoto() {
- var that = this;
- //拍照
- const ctx = wx.createCameraContext()
- ctx.takePhoto({
- quality: 'medium',//使用small可以加快速度
- success: (res) => {
- that.setData({
- src: res.tempImagePath //获取图片
- })
- //图片base64编码
- wx.getFileSystemManager().readFile({
- filePath: that.data.src, //选择图片返回的相对路径
- encoding: 'base64', //编码格式
- success: res => { //成功的回调
- that.setData({
- base64: res.data
- })
- that.myrquest();//拍照之后,调用上传函数,获取token上传人脸
- }
- })
- } //拍照成功结束
- }) //调用相机结束
- //失败尝试
- wx.showToast({
- title: '注册中...',
- icon: 'loading',
- duration: 1000
- })
- },
- error(e) {
- console.log(e.detail)
- },
- //获取用户信息
- bindGetUserInfo: function (e) {
- this.setData({
- nickName: e.detail.userInfo.nickName
- })
- wx.showToast({
- title: '授权成功',
- icon: 'success',
- duration: 500
- })
- },
- //先授权登陆,再拍照注册
- btnreg: function () {
- wx.showModal({
- title: '注册须知',
- content: '先授权登陆,再拍照注册哦!网络可能故障,如果不成功,请再试一下!'
- })
- }
- })
这里之前要多试几次,我之前以为可能由于网络的问题,会调用失败, 但其实是wx.request()是并发的,所以获取access_token和上传请求会冲突(可能没有获取到access_token就上传,会发生错误)。
解决办法是:将获取token和上传图片封装成一个函数,且将上传图片的request放在获取token的成功回调中,这样可避免出现access token is invalid or no longer valid. 错误。
(正确的代码就是上方给出的代码,不需要自己改)
另外,要开启微信小程序 IDE 的 不校验合法域名的选项(设置->项目设置 -> 勾选 不校验......)
至此,注册 就完成了(即获取用户昵称、拍照、上传人脸库注册。)
2.拍照上传在线人脸识别---登陆
找到指定用户组中与上传照片最相似的人脸并返回,比对结果。
我们仍然需要再建立一个页面来承载我们的登陆相关操作。就假定为 camera2{camera2.js camera2.wxml camera2.wxss camera2.json}
camera2.wxml
- <!-- camera.wxml -->
- <camera
- device-position="front"
- flash="off"
- binderror="error"
- style="width: 100%; height: 300px;"
- ></camera>
- <button type="primary" bindtap="takePhoto">拍照</button>
- <view>预览</view>
- <image mode="widthFix" src="{{src}}"></image>
camera2.js 与注册大同小异,区别是图片上传的接口不同(这次是 https://aip.baidubce.com/rest/2.0/face/v3/search 人脸搜素),获取access_token、拍照、照片base64编码都相同。
- // camera.js
- Page({
- data: {
- base64: "",
- token: "",
- msg: null,
- src: ''
- },
- //上传人脸进行验证(用于拍照后调用)
- myRequest: function () {
- var that = this;
- //acess_token获取
- wx.request({
- url: 'https://aip.baidubce.com/oauth/2.0/token', // 仅为示例,并非真实的接口地址
- data: {
- grant_type: 'client_credentials',
- client_id: '*********', //自己的API key
- client_secret: '*****************' //自己的Secrec Key
- },
- header: {
- 'Content-Type': 'application/json' // 默认值
- },
- success(res) {
- that.setData({
- token: res.data.access_token //获取到token
- //上传人脸进行 比对
- })
- wx.request({
- url: 'https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=' + that.data.token,
- method: 'POST',
- data: {
- image: that.data.base64, //change:使用that
- image_type: 'BASE64',
- group_id_list: '**********' //自己的用户组id
- },
- header: {
- 'Content-Type': 'application/json' // 默认值
- },
- success(res) {
- var errorcode = res.data.error_code
- if (errorcode == 0) //访问成功
- {
- var ulist = res.data.result
- //打印返回msg看看
- if (ulist.user_list != null) {
- // console.log('ulist存在');
- var result = ulist.user_list[0].score
- if (result > 80) {
- wx.showToast({
- title: '验证通过',
- icon: 'success',
- duration: 500
- })
- //验证通过,跳转到主界面
- wx.switchTab({
- url: '../UI/ui'//自己的
- })
- } else {
- console.log('不匹配')
- }
- }
- } else {
- console.log('访问失败')
- }
- }
- });
- }
- })
- },
- //拍照并编码
- takePhoto() {
- var that = this;
- //拍照
- const ctx = wx.createCameraContext()
- ctx.takePhoto({
- quality: 'medium',//使用small可加快速度
- success: (res) => {
- that.setData({
- src: res.tempImagePath
- })
- //图片base64编码
- wx.getFileSystemManager().readFile({
- filePath: that.data.src, //选择图片返回的相对路径
- encoding: 'base64', //编码格式
- success: res => { //成功的回调
- that.setData({
- base64: res.data
- })
- that.myRequest();//调用函数进行token获取和图片上传验证
- }
- })
- }
- })
- //失败重试提醒
- wx.showToast({
- title: '验证中...',
- icon: 'loading',
- duration: 1000
- })
- },
- error(e) {
- console.log(e.detail)
- }
- })
至此,我们的登陆也搞定了。
注意:上述的 登陆注册 是一个小程序的一个模块。关系如下
所以,需要在index页面中设置按钮,来跳转到注册以及登陆页面,然后注册登陆成功后,再跳转至其他功能页面。
后记
这次小程序实战,对我自己也是一个不小的挑战,对比各个云接口、看接口文档、查资料,耗费了大概十来天。但我相信大有裨益。另外,对我参考的博客和回答的诸位表示感谢。我们一起前进!
参考资料
【1】微信小程序开发文档
【2】百度云接口文档.v3版
打开小程序调试功能:
微信小程序 人脸识别登陆模块的更多相关文章
- 微信小程序---人脸识别(wx.startFacialRecognitionVerify)
1.由于人脸核验功能涉及到用户的敏感.隐私信息,因此调用此接口的业务方,需要满足一定的条件,申请小程序的人脸识别api.开通小程序后台的接口权限入口后,开发者可以登录mp.weixin.qq.com小 ...
- 微信小程序-人脸识别
wx.checkIsSupportFacialRecognition({success:res=>{ wx.startFacialRecognitionVerifyAndUploadVideo( ...
- 微信小程序人脸识别
参考:https://cloud.tencent.com/document/product/1007/31071
- 微信小程序+php 授权登陆,完整代码
先上图 实现流程: 1.授权登陆按钮和正文信息放到了同一个页面,未授权的时候显示登陆按钮,已授权的时候隐藏登陆按钮,显示正文信息,当然也可以授权和正文分开成两个页面,在授权页面的onlo ...
- ESA2GJK1DH1K微信小程序篇: 测试微信小程序APUConfig给WI-Fi模块配网并绑定设备,并通过MQTT控制设备
前言(源码使用介绍在最后) 一,微信小程序篇小程序下载(该源码为这节测试源代码) 二.有多少人一直在期盼着小程序可以实现SmartConfig或者Airkiss的功能? 来吧!我的这种方式包您满意. ...
- 【微信小程序】---授权登陆---【巷子】
Page({ onLoad: function() { var that = this; // 查看是否授权 wx.getSetting({ success: function(res) { if ( ...
- PHP实现微信小程序人脸识别刷脸登录功能
首先我们先确认我们的百度云人脸库里已经上传了我们的个人信息照片 然后我们在后台写刷脸登陆的接口login我们要把拍照获取的照片存储到服务器 public function login(){ // ...
- 微信小程序学习指南
作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 微信小程序导航:官方工具+精品教程+DEMO集合(1月7更新)
1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=14764346784612:简易教程:https://mp.weixin.qq.com/debug ...
随机推荐
- 读《图解HTTP》有感-(与HTTP协作的WEB服务器)
写在前面 Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等Web客户端提供文档: 一台web服务器可以搭建多个独立域名的web网站,也可以作为通信路径(路由)上的中 ...
- 浅谈java中的"=="和eqals区别
在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String(&qu ...
- Netty中如何写大型数据
因为网络饱和的可能性,如何在异步框架中高效地写大块的数据是一个特殊的问题.由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知ChannelFuture.当这种情况发生时,如 ...
- Redis的九大应用场景
毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象 ...
- Go笔记之二:一个完整的播放器示例
Go笔记之二:一个完整的播放器示例 该示例从命令行运行一个播放器示例,可进行添加.删除.浏览和模拟播放,其内容是对 Go 语言接口使用的良好展示 源码及可执行文件 参考书籍<Go语言编程> ...
- MySQL大量数据入库的性能比较
单位IM改版了用户聊天内容要存放在数据库. 一般JAVA Insert MySQL有如下几种方式1.自动提交Insert2.事务提交Insert3.批量提交4.使用Load File接口 模拟表结构如 ...
- 一文看懂 Github
GitHub 介绍 GitHub 是为开发者构建的一个开发平台.GitHub 是一个受开发者工作方式启发的开发平台,从开源到商业,能够在上面进行托管和查看代码.管理项目和数百万其他开发人员一起开发软件 ...
- selenium提供的截图功能
get_screenshot_as_file()提供一个截屏功能.在自动化执行过程中,执行失败后只能看到代码的运行错误,而不能直接看到ui上的错误,利用截屏保存下来很容易的进行问题的判断 先来执行一个 ...
- MySQL使用细节
************************************************************************ MySQL使用细节,包括部分常用函数以及注意如何提高数 ...
- bzoj 2759一个动态树好题
真的是动态树好题,如果把每个点的父亲设成p[x],那么建出来图应该是一个环套树森林,拆掉一条边,就变成了动态树,考虑维护什么,对于LCT上每个节点,维护两组k和b,一组是他到他父亲的,一组是他LCT子 ...