微信-支付宝---人脸识别认证

 人脸识别代码解读起来太复杂,以下代码大致就是微信支付宝人脸识别认证的全部流程,大约每一行代码都做了详细的注释,可能会有不完善的可以指出来,具体的业务逻辑后续会做进一步的整理说明。

 先引入进来几个封装的接口方法:

import { facewxauth, facewxback, wxSdk } from "@/api/module/base";
import wx from "weixin-js-sdk"; 

import axios from '@/libs/api.request'
import qs from 'qs'

//微信sdk
export const wxSdk = (data) => {
  return axios.request({
    url: '/auth/wx/jssdksignature.do',
    method: 'post',
    data: qs.stringify(data)
  })
}

//微信人脸识别初始化
export const facewxauth = (data) => {
  return axios.request({
    url: '/icard/face/wx-auth.do',
    method: 'post',
    data: qs.stringify(data)
  })
}

//微信人脸识别结果查询
export const facewxback = (data) => {
  return axios.request({
    url: '/icard/face/wx-auth-callback.do',
    method: 'post',
    data: qs.stringify(data)
  })
}

navigator是HTML中的内置对象,包含浏览器的信息;userAgent是navigator的属性方法,可以返回由客户机发送服务器的头部的值,可以判断用户使用哪个端的哪种浏览器打开页面。作用其实就是返回当前用户所使用的是什么浏览器,toLowerCase()是将转换为小写。

userAgent变量接收的信息在这里的意思就是当前用户所使用的浏览器信息,取得浏览器的userAgent字符串

let userAgent = window.navigator.userAgent.toLowerCase(); 

micromessenger为微信内嵌的浏览器 ,通过userAgent是否indexOf包含MicroMessenger来判断是否在微信内置浏览器打开网页 

let userAgent = window.navigator.userAgent.toLowerCase(); 

if (userAgent.indexOf("micromessenger") > -1) {
        // 代码执行进来,则表明是在微信内置的浏览器中操作的
        // 调用jssdk人脸核身校验
        let req = { userName: this.name, userCardNo: this.cardNo };
        //人脸识别前先进行一次初始化,调用微信人脸识别初始化封装接口的方法facewxauth(),传入参数为用户本人的信息
        facewxauth(req).then((res) => {
          // 用navigator.userAgent这种方法可以判断用户使用哪个端的哪种浏览器打开页面
          var u = navigator.userAgent,
            app = navigator.appVersion;
          // 取到浏览器信息,运行逻辑判断是哪个端打开的浏览器,这里判断是否是安卓端
          var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //g
          // match() ⽅法可在字符串内检索指定的值,或找到⼀个或多个正则表达式的匹配
          // 判断结果时这里判断是否是ios终端
          var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端

          // 取到人脸识别初始化成功后的结果 rsp
          let rsp = res.data;
;
          // 返回的code为200时,表明初始化成功了
          if (rsp.code == 200) {
            //   取到初始化成功后的数据 data1
            let data1 = rsp.data;

            // 调用微信jssdk
            let datas = {
              // 判断跳转的地址是安卓还是ios,两个不一样,所以需要判断一下
              url: isAndroid
                ? window.location.href
                : process.env.VUE_APP_BASE_URL +
                  process.env.VUE_APP_PUBLICPATH +
                  "faceauth",
            };

            //调用微信sdk封装接口的方法wxSdk(),接受一个参数是地址
            wxSdk(datas).then((res) => {
              // 把this的指向重新赋值
              var that = this;
              // 取到sdk接口调用成功返回的结果
              let data = res.data.data;
              // wx 就是引入的微信内的网页开发工具js-sdk包,所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用,通过config接口注入权限验证配置
              wx.config({
                beta: true, // 必填,开启内测接口调用,注入 wx.invoke 和 wx.on 方法
                debug: false, // 选填,开启调试模式,默认为 false 不开启
                appId: data.appid, // 必填,公众号的唯一标识
                timestamp: data.timeStamp, // 必填,生成签名的时间戳
                nonceStr: data.nonceStr, // 必填,生成签名的随机串
                signature: data.signature, // 必填,签名
                jsApiList: ["requestWxFacePictureVerify"], // 必填,需要使用的S接口列表
              });

              //config信息验证后会执行ready方法,从这里开始,算是开始人脸识别认证了,之前都是在做一些配置
              // 通过ready接口处理人脸识别成功验证
              wx.ready(function () {
                // 调用wx.invoke方法,传入3个参数,第一个参数是微信小程序或者网页人脸识别的接口认证requestWxFacePictureVerify,第二个参数是一个配置对象,对象含-调用微信sdk获取的appid,调用微信初始化接口获取的 userIdKey
                wx.invoke(
                  "requestWxFacePictureVerify",
                  {
                    // 调用微信sdk获取的appid
                    appId: data.appid,
                    // 调用微信初始化接口获取的 userIdKey ,这里是三元判断
                    request_verify_pre_info: data1.userIdKey
                      ? '{"user_id_key":"' + data1.userIdKey + '"}'
                      : "{}",
                    // check_alive_type人脸核验交互方式,为1屏幕闪烁
                    check_alive_type: "1",
                  },
                  // 代码执行回调到这说明,微信人脸识别接口验证通过
                  function (res) {
                    if (res.err_code == 0) {
                      that.$toast.loading({
                        message: "加载中...",
                        forbidClick: true,
                        duration: 0,
                      });
                      //如果res.err_code == 0就调用核身回调接口
                      //调用 微信人脸识别结果查询的接口
                      facewxback({ verifyResult: res.verify_result }).then(
                        (res) => {
                          // 清除loading提示效果
                          that.$toast.clear();
                          // 取到人脸识的结果用backRsp参数接收
                          let backRsp = res.data;
                          // 若code == 200此时就可以做人脸认证成功后的操作了
                          if (backRsp.code == 200) {
                            // 认证成功后如果是要跳转页面必须得用window.location.href跳转
                            window.location.href =
                              process.env.VUE_APP_BASE_URL +
                              process.env.VUE_APP_PUBLICPATH +
                              "home";
                          } else {
                            // 不成功即提示
                            this.$dialog({
                              title: "业务提示",
                              message: backRsp.msg,
                            }).then(() => {});
                          }
                        }
                      );
                    } else {
                      // 当res.err_code 不为 0时,进行错误业务提示
                      let ret = res.err_msg;
                      if (res.err_code) {
                        ret += " err_code: " + res.err_code;
                      }
                      this.$dialog({
                        title: "业务提示",
                        message: ret,
                      }).then(() => {});
                    }
                  }
                );
              });
            });
          } else {
            // 若人脸识别初始化失败,进行错误的业务提示
            this.$dialog({
              title: "业务提示",
              message: rsp.msg,
            }).then(() => {});
          }
        });
        // 如果是支付宝接口人脸认证的话
      } else if (userAgent.indexOf("alipayclient") > -1) {
        var that = this;
        // 调用支付宝的接口传入个人信息进行人脸识别初始化
        facezfbauth({ userName: this.name, userCardNo: this.cardNo }).then(
          (res) => {
            // 当code为200时,代表初始化成功了
            if (res.data.code == 200) {
              // 取到初始化成功后的结果用变量data接收
              let data = res.data.data;
              // 调用支付宝的AlipayJSBridge.call方法,端内接入支付宝h5页面,AlipayJSBridge是支付宝客户端通过bridge机制,允许前端H5页面通过特定的JS方法,AlipayJSBridge不需要任何的引用,是支付宝在window.load后直接存在的。这里接收3个参数,第一个startBizService接口发起请求认证,第一个唤起认证流程的参数对象,发起认证的信息包括certifyId和网关url,两者都通过服务端的相关接口取得,还有一个callback回调函数
              AlipayJSBridge.call(
                "startBizService",
                // 接入一个name对象,唤起认证流程,发起认证的信息包括certifyId和网关url,两者都通过服务端的相关接口取得。
                {
                  name: "open-certify",
                  param: JSON.stringify({
                    certifyId: data.certifyId,
                    url: data.certifyUrl,
                  }),
                },
                // 执行到回调函数这里认证结果回调就被触发了, 继续以下业务处理逻辑
                function (verifyResult) {
                  // 认证结果回调触发, 以下处理逻辑为示例代码,开发者可根据自身业务特性来自行处理
                  if (verifyResult.resultStatus === "9000") {
                    //verifyResult.resultStatus === "9000"代表 验证成功,接入方在此处处理后续的业务逻辑。
                    // 放一个loading加载状态
                    that.$toast.loading({
                      message: "加载中...",
                      forbidClick: true,
                      duration: 0,
                    });
                    // 验证成功,调用facezfbback()接口,传入一个证书ID参数
                    facezfbback({
                      certifyId: data.certifyId,
                    }).then((res) => {
                      // 验证成功后清除开启的loading
                      that.$toast.clear();
                      if (res.data.code == 200) {
                        // 判断验证结果code是否为200,是的话调整验证成功后的页面
                        window.location.href =
                          process.env.VUE_APP_API_BASE_URL +
                          process.env.VUE_APP_PUBLICPATH +
                          "/index";
                        return;
                      }
                    });
                  }
                  // 用户主动取消认证
                  if (verifyResult.resultStatus === "6001") {
                    // 可做下 toast 弱提示
                    that.$toast("已取消认证");
                  }
                }
              );
            }
          }
        );
      }

 另一个刷脸认证的逻辑代码,和上面几乎是大同小异的:

import wx from "weixin-js-sdk";
import { wxF, wxC, getInformation, zfbF, zfbC, wxSdk } from "@/api/module/auth";
import config from "@/config/index";
face() {
      var that = this;
      if (this.username == "" || this.usercard == "" || this.phone == "") {
        Dialog.alert({
          title: "业务提示",
          // message: backRsp.msg
          message: "请输入用户信息",
        }).then(() => {});
      } else {
        let userAgent = window.navigator.userAgent.toLowerCase(); //取得浏览器的userAgent字符串
        if (userAgent.indexOf("micromessenger") > -1) {
          //return new Promise((resolve , reject) => {
          let data = {
            authId: this.authId,
            phone: this.phone,
          };
          wxF(data).then((res) => {
            if (res.data.code == 200) {
              let data1 = res.data.data;
              var u = navigator.userAgent,
              // navigator.appVersion 属性可返回浏览器的平台和版本信息,该属性是一个只读的字符串
                app = navigator.appVersion;
              var isAndroid =
                u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //g
                // 检测 User-Agent 是否为 iOS 设备,ios设备发送请求的字符串信息是大概是这样Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1
              var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
              // 接下来需要判断跳转的页面url路径,跳转的是安卓端还是ios端,是安卓时就安卓端地址刷新当前页面,ios端时就跳转ios端页面
              let datas = {
                url: isAndroid
                  ? window.location.href
                  : "跳转地址",
              };
              wxSdk(datas).then((res) => {
                let data = res.data.data;
                wx.config({
                  beta: true, // 必填,开启内测接口调用,注入 wx.invoke 和 wx.on 方法
                  debug: false, // 选填,开启调试模式,默认为 false 不开启
                  appId: data.appid, // 必填,公众号的唯一标识
                  timestamp: data.timeStamp, // 必填,生成签名的时间戳
                  nonceStr: data.nonceStr, // 必填,生成签名的随机串
                  signature: data.signature, // 必填,签名,见附录1
                  jsApiList: [
                    "checkIsSupportFaceDetect",
                    "requestWxFacePictureVerify",
                  ],
                });
                that.show = true;
                wx.ready(function () {
                  wx.invoke(
                    "requestWxFacePictureVerify",
                    {
                      appId: data.appid,
                      request_verify_pre_info: data1.userIdKey
                        ? '{"user_id_key":"' + data1.userIdKey + '"}'
                        : "{}",
                      check_alive_type: "1",
                    },
                    function (res) {
                      if (res.err_code == 0) {
                        that.$toast.loading({
                          message: "加载中...",
                          forbidClick: true,
                          duration: 0,
                        });
                        //核心回调
                        wxC({
                          verifyResult: res.verify_result,
                          orderNo: data1.orderNo,
                          extend: data1.extend,
                        }).then((res) => {
                          let backRsp = res.data;
                          if (backRsp.code == 200) {
                            window.location.href =
                              config.domain +
                              config.context +
                              "/success?authType=" +
                              backRsp.data.authType;
                            that.$toast.clear();
                            that.show = false;
                            return;
                          } else {
                            Dialog.alert({
                              title: "业务提示",
                              message: "人脸认证未成功",
                            }).then(() => {});
                          }
                        });
                      } else {
                        Dialog.alert({
                          title: "业务提示",
                          message: "人脸认证未成功哟",
                        }).then(() => {
                          that.show = false;
                        });
                      }
                    }
                  );
                });
                wx.error(function (res) {
                  // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
                  console.log("config失败", res);
                });
              });
            } else {
              Dialog.alert({
                title: "业务提示",
                message: res.data.msg,
              }).then(() => {});
            }
          });
          //})
        } else if (userAgent.indexOf("alipayclient") > -1) {
          //验证支付宝版本
          // let v = this.compareVersion();
          // if (v == -1){
          //     Dialog.alert({
          //         title: '提示',
          //         message: '支付宝版本过低,无法使用人脸识别功能'
          //     }).then(() => {

          //     });

          // }else{
          zfbF({ authId: this.authId, phone: this.phone }).then((res) => {
            if (res.data.code == 200) {
              that.show = true;
              let data = res.data.data;
              AlipayJSBridge.call(
                "startBizService",
                {
                  name: "open-certify",
                  param: JSON.stringify({
                    certifyId: data.certifyId,
                    url: data.certifyUrl,
                  }),
                },
                function (verifyResult) {
                  // 认证结果回调触发, 以下处理逻辑为示例代码,开发者可根据自身业务特性来自行处理
                  if (verifyResult.resultStatus === "9000") {
                    that.$toast.loading({
                      message: "加载中...",
                      forbidClick: true,
                      duration: 0,
                    });
                    // 验证成功,接入方在此处处理后续的业务逻辑
                    zfbC({
                      certifyId: data.certifyId,
                      extend: data.extend,
                      orderNo: data.orderNo,
                    }).then((res) => {
                      if (res.data.code == 200) {
                        window.location.href =
                          config.domain +
                          config.context +
                          "/success?authType=" +
                          res.data.data.authType;
                        that.$toast.clear();
                        that.show = false;
                        return;
                      }
                    });
                  }
                  // 用户主动取消认证
                  if (verifyResult.resultStatus === "6001") {
                    that.show = false;
                    // 可做下 toast 弱提示
                    that.$toast("已取消认证");
                    // }else {
                    //     Dialog.alert({
                    //         title: '提示',
                    //         message: '人脸认证失败'
                    //     }).then(() => {

                    //     });
                  }
                  //const   errorCode = verifyResult.result && verifyResult.result.errorCode ;
                  // 其他结果状态码判断和处理 ...
                }
              );
              /**
               * 唤起认证流程
               * 参数: certifyId、url 需要通过支付宝 openapi 开放平台网关接口获取
               * 详细说明可查看文档下方的参数说明
               **/
            }
          });
          //}
        }
      }
    },

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值