概述

AI人脸识别,使用官方API:腾讯云人脸核身之独立H5接入。接口官方返回code = 0 表示成功,其他code码值均为对应码值信息,详见错误码。
注意:
1.合作方上送身份信息的计算签名参数与启动人脸核身计算签名参数不一致,有部分区别。
2.wbappid = webankAppId = app_id(如果我没理解错的话,API中介绍命名不同)
3.建议token和signticket一起做下20分钟定时刷新机制,保证缓存里的signticket是最新并且有效的

实现流程

合作方后台上送身份信息

  1. 前端入参:客户身份证号、客户姓名、from(App || browser)
  2. 后端固定参数:wbappid = webankAppId = app_id(API中介绍命名不同,注意)、orderNo(可自定义随机生成不唯一)、userId(可自定义随机生成不唯一)、version
  3. 获取signTicket(通过token)---- 获取方式代码见下
  4. 计算合作方上送身份信息签名,参数有:wbappid、orderNo、name、idNo、userId、version、signTicket ---- 计算方式代码见下

启动H5人脸核身

  1. 在合作方成功上送身份信息后,可以获取到h5faceId
  2. 获取nonce(32位随机数)
  3. 获取nonceTicket(通过token & userId)
  4. 计算启动H5人脸核身签名,参数有:wbappid、orderNo、userId、version、h5faceId、nonce、nonceTicket
  5. 将成功拉起人脸核身验证通过后的回调页面链接配置至配置文件,同时对该链接进行encode编码
  6. 获取到所有拉起人脸核身所需参数后,向链接https://ida.webank.com/api/web/login拼接上参数:webankAppId、version、nonce、orderNo、h5faceId、url、sign、from、userId。例如:
https://ida.webank.com/api/web/login?webankAppId="+wbappid+"&version=1.0.0&nonce="+nonce+"&orderNo="+orderNo+"&h5faceId="+h5faceId+"&url="+url+"&userId="+userId+"&sign="+sign+"&from="+userVo.getFrom()+"

拼接好后,直接将该链接返回前端去打开即可拉起人脸核身。请注意,该链接仅一次有效!!!

核心代码实现

获取accessToken

    @Overridepublic String getToken(){String accessTokenTencent = (String) redisService.get("accessTokenTencent");log.info("获取redis中的accessToken,为:[{}]", accessTokenTencent);if ("".equals(accessTokenTencent) || accessTokenTencent == null) {Map<String, String> param = new HashMap<>(16);String tokenUrl = "https://idasc.webank.com/api/oauth2/access_token?app_id={app_id}&secret={secret" +"}&grant_type={grant_type}&version=1.0.0";param.put("app_id", wbappid);param.put("secret", secret);param.put("grant_type", "client_credential");TencentTokenDto tokenDto = template.getForObject(tokenUrl, TencentTokenDto.class, param);if (!"0".equals(tokenDto.getCode())) {log.error("获取腾讯token信息错误,errorCde:{},errMessage:{}", tokenDto.getCode(), tokenDto.getMsg());return "";}accessTokenTencent = tokenDto.getAccessToken();redisService.set("accessTokenTencent", accessTokenTencent, 6800L);}log.info("返回有效accessToken,为:[{}]", accessTokenTencent);return accessTokenTencent;}

通过accessToken获取signTicket

@Overridepublic String getSignTicket(String txAccessToken){String signTicket = (String) redisService.get("signTicket");log.info("获取redis中的signTicket,为:[{}]", signTicket);if ("".equals(signTicket) || signTicket == null) {Map<String, String> param = new HashMap<>(16);String tokenUrl = "https://idasc.webank.com/api/oauth2/api_ticket?app_id={app_id}&access_token" +"={access_token}&type={type}&version=1.0.0";param.put("app_id", wbappid);param.put("access_token", txAccessToken);param.put("type", "SIGN");TencentTicketDto ticketDto = template.getForObject(tokenUrl, TencentTicketDto.class, param);if (!"0".equals(ticketDto.getCode())) {log.error("获取腾讯signTicket信息错误,errorCde:{},errMessage:{}", ticketDto.getCode(), ticketDto.getMsg());return "";}signTicket = ticketDto.getTickets().get(0).getValue();redisService.set("signTicket", signTicket, 3000L);}log.info("返回有效signTicket,为:[{}]", signTicket);return signTicket;}

合作方上送身份信息计算签名

@Overridepublic String sign(String orderNo, String idNo, String name, String signTicket, String userId) {//为计算签名做准备List<String> list = new ArrayList<>();String version = "1.0.0";list.add(wbappid);list.add(orderNo);list.add(name);list.add(idNo);list.add(userId);list.add(version);String sign = getSign(list, signTicket);return sign;}
private String getSign(List<String> values, String signTicket) {if (values == null) {throw new NullPointerException("values is null");}// remove nullvalues.removeAll(Collections.singleton(null));values.add(signTicket);log.info("启动人脸核身签名排序前参数为:[{}]",values);java.util.Collections.sort(values);log.info("启动人脸核身签名排序后参数为:[{}]",values);StringBuilder sb = new StringBuilder();for (String s : values) {sb.append(s);}return Hashing.sha1().hashString(sb, Charsets.UTF_8).toString().toUpperCase();}

合作方上送身份信息

@Overridepublic TxCodeDto sendUserInfo(UserVo userVo){//获取accessTokenString accessToken = getToken();//获取signTicketString signTicket = getSignTicket(accessToken);//合作方上送计算签名String sign = sign(userVo.getOrderNo(), userVo.getIdNo(), userVo.getName(), signTicket, userVo.getUserId());Map<String, String> param = new HashMap<>(16);param.put("webankAppId", wbappid);param.put("orderNo", userVo.getOrderNo());param.put("name", userVo.getName());param.put("idNo", userVo.getIdNo());param.put("userId", userVo.getUserId());param.put("version", "1.0.0");param.put("sign", sign);log.debug("合作方上送身份信息参数有:[{}]", param);String url = "https://idasc.webank.com/api/server/h5/geth5faceid";HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntity<Map> entity = new HttpEntity<>(param, headers);TxCodeDto txCodeDto = this.template.postForObject(url, entity, TxCodeDto.class);log.info("合作方上送身份信息接口返回:[{}]", txCodeDto);return txCodeDto;}

通过accessToken & userId获取nonceTicket

@Overridepublic String getNonceTicket(String txAccessToken, String userId){String nonceTicket = (String) redisService.get("nonceTicket");log.info("获取redis中的nonceTicket,为:[{}]", nonceTicket);if ("".equals(nonceTicket) || nonceTicket == null) {Map<String, String> param = new HashMap<>(16);String tokenUrl = "https://idasc.webank.com/api/oauth2/api_ticket?app_id={app_id}&access_token" +"={access_token}&type={type}&version=1.0.0&user_id={user_id}";param.put("app_id", wbappid);param.put("access_token", txAccessToken);param.put("type", "NONCE");param.put("user_id", userId);log.info("获取腾讯NONCE ticket,为:[{}]", param);TencentTicketDto ticketDto = template.getForObject(tokenUrl, TencentTicketDto.class, param);if (!"0".equals(ticketDto.getCode())) {log.error("获取腾讯NONCE ticket信息错误,errorCde:{},errMessage:{}", ticketDto.getCode(), ticketDto.getMsg());return "";}nonceTicket = ticketDto.getTickets().get(0).getValue();redisService.set("nonceTicket", ticketDto.getTickets().get(0).getValue(), 100L);}log.info("返回有效nonceTicket,为:[{}]", nonceTicket);return nonceTicket;}

启动人脸核身计算签名

private String faceSign(String orderNo, String userId, String nonceTicket, String h5faceId, String nonce) {//为计算签名做准备List<String> list = new ArrayList<>();list.add(wbappid);list.add(orderNo);list.add(userId);list.add("1.0.0");list.add(h5faceId);list.add(nonce);String sign = getSign(list, nonceTicket);log.info("启动人脸核身返回签名为:[{}]",sign);return sign;}

启动人脸核身获取启动链接

 @Overridepublic String startCheckFace(UserVo userVo){//随机生成32位唯一用户ID和订单IDString userId = getOrderNoOrUserIdRandom(32,"userId");String orderNo = getOrderNoOrUserIdRandom(32,"orderNo");userVo.setOrderNo(orderNo);userVo.setUserId(userId);String requestUrl = "";try {//获取accessTokenString accessToken = getToken();//上送合作方用户信息TxCodeDto txCodeDto = sendUserInfo(userVo);if(!"0".equals(txCodeDto.getCode())){log.info("启动人脸核身--上送合作方用户信息异常,异常原因为:[{}]]",txCodeDto.getMsg());return requestUrl;}//获取h5/geth5faceid 接口返回的唯一标识String h5faceId = txCodeDto.getResult().getH5faceId();//获取32位随机数String nonce = getRandom();//获取nonceTicketString nonceTicket = getNonceTicket(accessToken, userId);//启动人脸核身计算签名String sign = faceSign(orderNo, userId, nonceTicket,h5faceId,nonce);//成功拉起人脸识别并识别成功或失败后的回调路径String path = "http://127.0.0.1:8080/#/start?state=";log.debug("人脸核身通过后的回调地址-拼接路径加密前:url = [{}]",path);String url = getURLEncoderString(path);log.debug("人脸核身通过后的回调地址-拼接路径加密后:url = [{}]",url);requestUrl = "https://ida.webank.com/api/web/login?webankAppId="+wbappid+"&version=1.0.0&nonce="+nonce+"&orderNo="+orderNo+"&h5faceId="+h5faceId+"&url="+url+"&userId="+userId+"&sign="+sign+"&from="+userVo.getFrom()+"";} catch (Exception e) {log.error("启动人脸核身异常,异常原因为:[{}]",e.getMessage());}log.info("启动人脸核身--请求路径为:[{}]]",requestUrl);return requestUrl;}

postMan调用示例:

H5人脸核身结果跳转

验证结果之前端获取结果验证签名

/*** 前端获取结果验证签名* @param checkVo*/@Overridepublic String checkSign(CheckVo checkVo) {//获取accessTokenString accessToken = getToken();//获取signTicketString signTicket = getSignTicket(accessToken);List<String> list = new ArrayList<>();list.add(wbappid);list.add(checkVo.getOrderNo());list.add(checkVo.getCode());String sign = getSign(list, signTicket);log.info("前端获取结果验证签名值为:[{}]",sign);return sign;}

服务端验证结果

/*** 服务端验证结果* @param checkVo* @return*/@Overridepublic ServerResultDto serverCheck(CheckVo checkVo) {//注意,随机数需要保持一致checkVo.setRandom(getRandom());String sign = serverSign(checkVo);Map<String, String> param = new HashMap<>(16);String url = "https://idasc.webank.com/api/server/sync?app_id={app_id}&nonce={nonce}&order_no={order_no}&version=1.0.0&sign={sign}&get_file={get_file}";param.put("app_id", wbappid);param.put("nonce", checkVo.getRandom());param.put("order_no", checkVo.getOrderNo());param.put("sign", sign);param.put("get_file", "1");log.debug("服务端验证结果参数有:[{}]", param);TxServerDto txServerDto = this.template.getForObject(url,TxServerDto.class,param);if (!"0".equals(txServerDto.getCode())) {log.error("服务端验证结果信息错误,errorCde:{},errMessage:{}", txServerDto.getCode(), txServerDto.getMsg());return null;}return txServerDto.getResult();}

AI-腾讯云人脸核身之独立H5接入相关推荐

  1. AI 腾讯云人脸核身之独立H5接入

    文章目录 一.概述 二.合作方后台上送身份信息~实现流程 2.1. 前端入参 2.2. 后端固定参数 2.3. 获取 Access Token 2.4. 获取 SIGN ticket 2.5. 生成签 ...

  2. java腾讯云人脸核身移动浮层H5接入

    腾讯云人脸核身文档 最近公司有业务需求,需要对企业微信中的小程序添加人脸识别功能,一般的人脸核身是对app中添加sdk完成的,考虑到业务需要,采用腾讯云的移动浮层H5接入,废话不多说,直接上代码. 这 ...

  3. 微信公众号HTML5接入腾讯云人脸核身

    微信公众号HTML5接入腾讯云人脸核身 概述 接入流程 原生H5对行业的要求 概述 针对微信公众号接入腾讯云,腾讯云提供了两种方案,一种是通用H5接入,另外一种是通过微信的原生H5来接入,但是一般都是 ...

  4. 腾讯云人脸核身和人脸识别是什么

    腾讯云人脸核身和人脸识别是什么 有一些客户过来咨询的时候都是拿着腾讯云人脸识别的链接来问能不能做实名认证判断这个人的身份,但是在腾讯云中能做实名认证上传身份证的叫做人脸核身,腾讯云的人脸识别是居于腾讯 ...

  5. Android 快速接入腾讯云人脸核身(识别)

    Android 通过 SDK 快速接入腾讯云人脸核身 我的接入代码:https://blog.csdn.net/qq_39836064/article/details/108702725,很久之前写的 ...

  6. 腾讯云人脸核身uniapp+后端代码

    项目开发中用到了腾讯人脸验证的模块,中间也踩了一些坑,这里发帖记录一下,留待自己后续查验. 首先说后端,这里用java开发的,官方的文档地址是:人脸核身 实名核身鉴权 - API 文档 - 文档中心 ...

  7. 腾讯云人脸核身相关问题

    如何申请腾讯云人脸核身的接入? 打开腾讯云 介绍页 ,单击页面上的[立即申请],填写具体业务需求并上传工商营业执照,提交接入申请即可. 申请使用腾讯云慧眼人脸核身有哪些限制? 申请开通人脸核身服务是没 ...

  8. vue+springboot+腾讯云人脸核身

    目录 业务场景 腾讯云 后台部分 前台部分 业务场景 业务场景,VUE做PC端,然后要用户输入姓名和身份证号点击生成二维码,微信扫描进行人脸识别,最后识别后,页面显示认真成功失败. 腾讯云 开始先登录 ...

  9. AI技术实践 | 人脸核身在未成年人保护领域的实践应用

    未成年人保护工作需要多方协同,注重未成年人健康网络习惯的培养.在技术向善的理念下,人工智能技术又该如何落到实处呢? 接下来,本文将详细讲述如何接入腾讯云慧眼·智能身份认证能力助力未成年人保护. 1.准 ...

最新文章

  1. 新手探索NLP(六)——全文检索
  2. 可执行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...
  3. 汇新杯┃拼多多黄峥:普通的创业者,不普通的朋友圈_创成汇
  4. linux网卡IP同一网段,Linux下多网卡不同IP在同一网段的情况
  5. python 进程池、线程池 与异步调用、回调机制
  6. Cetnos环境下inotify+rsync实时同步
  7. mfc 子窗体 按钮不触发_python项目实战:pyQT5 实现窗体之间传值
  8. python之路day9_Python之路,Day7 - 面向对象编程进阶
  9. windows中定时同步文件
  10. 【Python】爬虫-----下载B站视频
  11. 知识经济杂志知识经济杂志社知识经济编辑部2022年第33期目录
  12. 表格说超链接危害计算机怎么办,win10系统excel表格中的超链接打不开提示“由于本机限制”的处理教程...
  13. 人可以活很多次,但是七年就是一辈子
  14. Numpy中的Boardcast机制
  15. 2014-2015 少年辛苦终身事,莫向光阴惰寸功
  16. [Zookeeper] 安装and各 配置参数详解
  17. 机器学习基础:概率和熵
  18. Android tips(十二)--Android开发中使用矢量图
  19. m认知无线电信号检测算法matlab仿真,能量检测,循环平稳检测以及自相关检测
  20. 关于计算机类的SAS论文,浅析SAS软件教学中内容与形式的结合论文

热门文章

  1. 16、【易混淆概念集】-第十章 沟通方法 会议 沟通渠道计算 沟通管理计划
  2. Vr pat 文件后处理
  3. Ubuntu_ROS中应用kinect v2笔记
  4. 国学堂—梁冬对话林曦
  5. 10-Secret安全存储
  6. sparrow-js·场景化低代码搭建-了解一下
  7. 画论79 张庚《浦山论画》
  8. 不通过App Store,在iOS设备上直接安装应用程序
  9. Excel如何把事务型数据转化为可以直接关联性分析数据
  10. nmap的官网下载安装、简单命令的抓包测试