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

文章目录

          • 一、概述
          • 二、合作方后台上送身份信息~实现流程
            • 2.1. 前端入参
            • 2.2. 后端固定参数
            • 2.3. 获取 Access Token
            • 2.4. 获取 SIGN ticket
            • 2.5. 生成签名
            • 2.6. 合作方后台上送身份信息
          • 三、启动H5人脸核身
            • 3.1. 获取h5faceId
            • 3.2. 获取nonce
            • 3.3. 获取nonceTicket
            • 3.4. 计算启动签名
            • 3.5. 构建回调页面链接
          • 四、查询核身结果
            • 4.1. 启动H5人脸核身

一、概述

人脸识别,使用官方API:腾讯云人脸核身之独立H5接入。接口官方返回code = 0 表示成功,其他code码值均为对应码值信息,详见错误码。
注意:
1.合作方上送身份信息的计算签名参数与启动人脸核身计算签名参数不一致,有部分区别。
2.wbappid = webankAppId = app_id

二、合作方后台上送身份信息~实现流程
2.1. 前端入参

前端入参:客户身份证号、客户姓名、用户 ID (userId)、from(App || browser)
controller

    @Autowiredprivate PCH5SendIdentityService pch5SendIdentityService;/*** 合作方后台上送身份信息 PC H5* 文档:https://cloud.tencent.com/document/product/1007/35893* <p>* 请求 URL:https://miniprogram-kyc.tencentcloudapi.com/api/server/h5/geth5faceid?orderNo=xxx* 请求方法:POST* 报文格式:Content-Type: application/json* </p>** @param faceDetectUserVO 身份信息*/@PostMapping("/sendH5IdentityInfoUserInfo")public TXH5IdentityInfoDTO sendH5IdentityInfoUserInfo(@RequestBody FaceDetectUserVO faceDetectUserVO) {return pch5SendIdentityService.sendH5IdentityInfoUserInfo(faceDetectUserVO);}

entity

@Data
@AllArgsConstructor
@NoArgsConstructor
public class FaceDetectUserVO {// https://cloud.tencent.com/document/product/1007/35893private String name;//姓名private String idNo;//证件号码private String userId;//用户 ID ,用户的唯一标识(不能带有特殊字符),需要跟生成签名的 userId 保持一致private String from;//来源 App || browser)
}
2.2. 后端固定参数

后端固定参数:wbappid = webankAppId = app_id(API中介绍命名不同,注意)、orderNo(可自定义随机生成不唯一)、userId(可自定义随机生成不唯一)、version

2.3. 获取 Access Token

https://cloud.tencent.com/document/product/1007/57603

 /*** 获取 access_token* 文档: https://cloud.tencent.com/document/product/1007/37304** @return*/@Overridepublic String getAccessTokenTencent() {// 从redis中获取accessTokenTencentString accessTokenTencent = redisUtils.get("accessTokenTencent");log.info("获取redis中的accessToken,为:[{}]", accessTokenTencent);if (StringUtils.isEmpty(accessTokenTencent)) {String accessTokenUrl = String.format(TencentCloudConfig.ACCESS_TOKEN_URL, appId, secret);String jsonStr = HttpUtil.doGet(accessTokenUrl, null);log.info("返回报文;->{}", jsonStr);Map<String, String> jsonMap = ConvertUtils.stringToMap(jsonStr);if (!"0".equals(jsonMap.get("code"))) {String msg = jsonMap.get("msg");log.error("获取腾讯token信息错误,code:{},msg:{}", jsonMap.get("code"), msg);GraceJSONResult.errorMsg(msg);/*** 错误响应示例:* {*     "code": "66660000",*     "msg": "请求参数异常",*     "bizSeqNo": "22090720001184453210262184859700",*     "transactionTime": "20220907102621",*     "success": false,*     "expire_in": 0* }*/}/*** 正确响应示例:* {*  "code":"0","msg":"请求成功",*  "transactionTime":"20151022043831",*  "access_token":"accessToken_string",*  "expire_time":"20151022043831",*  "expire_in":"7200"* }*/// 获取 access_tokenaccessTokenTencent = jsonMap.get("access_token");// 过期时间 默认7200L  设置6800L提前重新获取redisUtils.set("accessTokenTencent", accessTokenTencent, 6800L);}log.info("返回有效accessToken,为:[{}]", accessTokenTencent);return accessTokenTencent;}
2.4. 获取 SIGN ticket

https://cloud.tencent.com/document/product/1007/57613
通过token获取signTicket

 /*** 获取 SIGN ticket* 请求地址: http://localhost:9900/getSignTicketTencent* 文档: https://cloud.tencent.com/document/product/1007/37305** @param accessTokenTencent access_token* @return*/@Overridepublic String getSignTicketTencent(String accessTokenTencent) {// 从redis中获取nonceTicketTencentString signTicketTencent = redisUtils.get("signTicketTencent");log.info("获取redis中的signTicketTencent,为:[{}]", signTicketTencent);String signTicketValue = null;if (StringUtils.isEmpty(signTicketTencent)) {String getSignTicketUrl = String.format(TencentCloudConfig.SIGN_TICKET_URL, appId, accessTokenTencent);String jsonStr = HttpUtil.doGet(getSignTicketUrl, null);log.info("返回报文;->{}", jsonStr);TicketDTO ticketDTO = JSON.parseObject(jsonStr, TicketDTO.class);if (!"0".equals(ticketDTO.getCode())) {String msg = ticketDTO.getMsg();log.error("获取腾讯signTicket信息错误,code:{},msg:{}", ticketDTO.getCode(), msg);GraceJSONResult.errorMsg(msg);}/*** 正确响应示例:* {*       "code": "0",*       "msg": "请求成功",*       "transactionTime": "20151022044027",*       "tickets": [*         {*              "value": "ticket_string",*              "expire_in": "3600",*              "expire_time": "20151022044027"*         }*     ]* }*/signTicketValue = ticketDTO.getTickets().get(0).getValue();// 过期时间 默认3600L  设置3200L提前重新获取redisUtils.set("signTicketTencent", signTicketValue, 3000L);}return signTicketValue;}
2.5. 生成签名

计算合作方上送身份信息签名,参数有:wbappid、orderNo、name、idNo、userId、version、signTicket
在这里插入图片描述
计算签名

  /*** PC 端 H5 接入 > 合作方上送身份信息计算签名* 文档地址:https://cloud.tencent.com/document/product/1007/35893** @param faceDetectUserVO* @param signTicket* @return*/public String signH5(FaceDetectUserVO faceDetectUserVO, String signTicket) {//为计算签名做准备//为计算签名做准备List<String> list = new ArrayList<>();list.add(appId);list.add(faceDetectUserVO.getOrderNo());list.add(faceDetectUserVO.getName());list.add(faceDetectUserVO.getIdNo());list.add(faceDetectUserVO.getUserId());list.add(TencentCloudConfig.VERSION);return SignUtils.getSign(list, signTicket);}
2.6. 合作方后台上送身份信息
/*** 合作方后台上送身份信息 PC H5* 文档:https://cloud.tencent.com/document/product/1007/35893* <p>* 请求 URL:https://miniprogram-kyc.tencentcloudapi.com/api/server/h5/geth5faceid?orderNo=xxx* 请求方法:POST* 报文格式:Content-Type: application/json* </p>** @param faceDetectUserVO 身份信息* @return*/@Overridepublic TXH5IdentityInfoDTO sendH5IdentityInfoUserInfo(FaceDetectUserVO faceDetectUserVO) {//获取accessTokenString accessToken = commonIdentityService.getAccessTokenTencent();//获取signTicketString signTicket = commonIdentityService.getSignTicketTencent(accessToken);//订单号String orderNo = SignUtils.GenerateRandom32Number(32);faceDetectUserVO.setOrderNo(orderNo);//合作方上送计算签名String sign = signH5(faceDetectUserVO, signTicket);Map<String, String> param = new HashMap<>(16);param.put("webankAppId", appId);param.put("orderNo", orderNo);param.put("name", faceDetectUserVO.getName());param.put("idNo", faceDetectUserVO.getIdNo());param.put("userId", faceDetectUserVO.getUserId());param.put("version", TencentCloudConfig.VERSION);param.put("sign", sign);log.debug("合作方上送身份信息参数有:[{}]", param);String getFaceidUrl = String.format(TencentCloudConfig.GET_H5_FACEID_URL, orderNo);String jsonStr = HttpUtil.doPost(getFaceidUrl, JSON.toJSONString(param));log.info("返回报文;->{}", jsonStr);TXH5IdentityInfoDTO txh5IdentityInfoDTO = JSON.parseObject(jsonStr, TXH5IdentityInfoDTO.class);log.info("合作方上送身份信息接口返回:[{}]", txh5IdentityInfoDTO);return txh5IdentityInfoDTO;}
三、启动H5人脸核身
3.1. 获取h5faceId

在合作方成功上送身份信息后,可以获取到h5faceId

3.2. 获取nonce

(32位随机数)

3.3. 获取nonceTicket

获取nonceTicket(通过token & userId)

3.4. 计算启动签名

https://cloud.tencent.com/document/product/1007/61074
计算启动H5人脸核身签名,参数有:wbappid、orderNo、userId、version、h5faceId、nonce、nonceTicket
在这里插入图片描述

   /*** 启用 H5 人脸认证 人脸核身计算签名* 文档:https://cloud.tencent.com/document/product/1007/35894** @param orderNo     订单号,字母/数字组成的字符串,本次人脸验证合作伙伴上送的订单号,唯一标识* @param userId      用户 ID ,用户的唯一标识(不要带有特殊字符)* @param nonceTicket 合作伙伴服务端实时获取的 tikcet,注意是 NONCE 类型* @param h5faceId    h5/geth5faceid 接口返回的唯一标识* @param nonce       随机数:32位随机串(字母+数字组成的随机数)* @return*/private String faceSignH5(String orderNo, String userId, String nonceTicket, String h5faceId, String nonce) {//为计算签名做准备List<String> list = new ArrayList<>();list.add(appId);list.add(orderNo);list.add(userId);list.add(TencentCloudConfig.VERSION);list.add(h5faceId);list.add(nonce);String sign = SignUtils.getSign(list, nonceTicket);log.info("启动人脸核身返回签名为:[{}]", sign);return sign;}
3.5. 构建回调页面链接

将成功拉起人脸核身验证通过后的回调页面链接配置至配置文件,同时对该链接进行encode编码
获取到所有拉起人脸核身所需参数后,向链接https://ida.webank.com/api/web/login拼接上参数:webankAppId、version、nonce、orderNo、h5faceId、url、sign、from、userId。例如:

https://ida.webank.com/api/web/login?webankAppId=%s&version=1.0.0&nonce=%s&orderNo=%s&h5faceId=%s&url&userId=%s&sign=%s&from=%s

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

/*** 构造人脸核身获取启动链接* 文档:https://cloud.tencent.com/document/product/1007/35894** @param faceDetectUserVO* @return*/@Overridepublic GraceJSONResult startCheckFace(FaceDetectUserVO faceDetectUserVO) {//随机生成32位唯一用户ID和订单IDString userId = SignUtils.GenerateRandom32Number(32);String orderNo = SignUtils.GenerateRandom32Number(32);faceDetectUserVO.setOrderNo(orderNo);faceDetectUserVO.setUserId(userId);String requestUrl = "";try {//获取accessTokenString accessToken = commonIdentityService.getAccessTokenTencent();//上送合作方用户信息TXH5IdentityInfoDTO txh5IdentityInfoDTO = sendH5IdentityInfoUserInfo(faceDetectUserVO);if (!"0".equals(txh5IdentityInfoDTO.getCode())) {String msg = txh5IdentityInfoDTO.getMsg();log.info("启动人脸核身--上送合作方用户信息异常,异常原因为:[{}]]", msg);GraceJSONResult.errorMsg(msg);}//获取h5/geth5faceid 接口返回的唯一标识String h5faceId = txh5IdentityInfoDTO.getResult().getH5faceId();//获取32位随机数String nonce = SignUtils.GenerateRandom32Number(32);//获取nonceTicketString nonceTicket = commonIdentityService.getNonceTicketTencent(accessToken, userId);//启动人脸核身计算签名String sign = faceSignH5(orderNo, userId, nonceTicket, h5faceId, nonce);//成功拉起人脸识别并识别成功或失败后的回调路径String oauthCallback = TencentCloudConfig.OAUTH_CALLBACK_URL;log.debug("人脸核身通过后的回调地址-拼接路径加密前:url = [{}]", oauthCallback);String oauthRedirectUrl = URLEncoder.encode(oauthCallback, "utf-8");log.debug("人脸核身通过后的回调地址-拼接路径加密后:url = [{}]", oauthRedirectUrl);/*** https://miniprogram-kyc.tencentcloudapi.com/api/pc/login?webankAppId=appId001* &version=1.0.0* &nonce=4bu6a5nv9t678m2t9je5819q46y9hf93* &orderNo=161709188560917432576916585* &h5faceId=wb04f10695c3651ce155fea7070b74c9* &url=https%3a%2f%2fcloud.tencent.com* &userId=23333333333333* &sign=5DD4184F4FB26B7B9F6DC3D7D2AB3319E5F7415F*/requestUrl = String.format(TencentCloudConfig.REQUEST_URL, appId, nonce, orderNo, h5faceId, oauthRedirectUrl, userId, sign, faceDetectUserVO.getFrom());} catch (Exception e) {log.error("启动人脸核身异常,异常原因为:[{}]", e.getMessage());}log.info("启动人脸核身--请求路径为:[{}]]", requestUrl);return GraceJSONResult.ok(requestUrl);}
四、查询核身结果
4.1. 启动H5人脸核身

在这里插入图片描述
在这里插入图片描述

    /*** 前端获取结果验证签名* API:https://cloud.tencent.com/document/product/1007/61302** @param orderNo 订单号,字母/数字组成的字符串,本次人脸核身合作伙伴上送的订单号,唯一标识* @return*/private String getCheckSign(String orderNo) {//获取accessTokenString accessToken = commonIdentityService.getAccessTokenTencent();//获取signTicketString signTicket = commonIdentityService.getSignTicketTencent(accessToken);List list = new ArrayList<>();list.add(appId);list.add(orderNo);list.add(TencentCloudConfig.VERSION);list.add(SignUtils.GenerateRandom32Number(32));String sign = SignUtils.getSign(list, signTicket);log.info("前端获取结果验证签名值为\"[{}]", sign);return sign;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最佳实践:使用阿里云CDN加速OSS访问

简介&#xff1a; 用户直接访问OSS资源&#xff0c;访问速度会受到OSS的下行带宽以及Bucket地域的限制。如果通过CDN来访问OSS资源&#xff0c;带宽上限更高&#xff0c;并且可以将OSS的资源缓存至就近的CDN节点&#xff0c;通过CDN节点进行分发&#xff0c;访问速度更快&#…

IDEA 2022 CPU占用100%的问题及解决方法

禁用下面这三个插件然后重启IDEA即可&#xff1a; Package Checker Package Search Ktor 下面的内容可以不用看了&#xff0c;只要禁用这仨插件就行

无服务计算应用场景探讨及 FaaS 应用实战

简介&#xff1a; 无服务计算本身是一个概念或者理论模型&#xff0c;落地到具体技术上主要有函数即服务&#xff08;FaaS&#xff09;以及后端即服务&#xff08;BaaS&#xff09;两种形式&#xff0c;阿里云提供函数即服务 FaaS 产品。 作者 | 宋文龙&#xff08;闻可&#x…

想学 Python?那这套教程再适合你不过了!!

如果你想问最近这些年什么编程语言最值得学习&#xff0c;我相信很多人都会告诉你是Python&#xff01;所以不仅是开发小白&#xff0c;甚至很多开发老手&#xff0c;也都开始学习Python&#xff0c;作为辅助第二语言来提高自己的职场竞争力。不过结合我最近这些年Python的学习…

2020-09-01

简介&#xff1a; 《5天入门视觉AI》电子书来了&#xff01;身份证识别、电子相册两大实践场景带你快速入门视觉AI应用开发&#xff01; 阿里云“在家实践”全新出击&#xff01; 《5天入门视觉AI》电子书正式上线&#xff01; 视觉AI训练营必备教材&#xff01; 身份证识别、电…

再见 Nacos,我要玩 Service Mesh 了!

作者 | 姜桥出品 | CSDN云计算&#xff08;ID:CSDNcloud&#xff09;前面的文章<<干货|如何步入Service Mesh微服务架构时代>>实战演练了Service Mesh微服务架构的具体玩法&#xff0c;该案例中通过IstioKubernetes的组合&#xff0c;一组以Spring Boot框架开发的服…

顶会论文看不懂?阿里巴巴技术专家为你全方位解读!

简介&#xff1a; 由阿里云开发者社区联合新零售智能引擎事业群共同打造的《KDD 论文精华解读》电子书重磅发布&#xff01;覆盖推荐系统、图神经网络预训练、买家秀视频标题生成、在线电视剧的受众竞争力预测和分析等 10 内容&#xff0c;免费下载电子书感受科技的震撼&#x…

Python C扩展的引用计数问题探讨

简介&#xff1a; # Python GC机制 对于Python这种高级语言来说&#xff0c;开发者不需要自己管理和维护内存。Python采用了引用计数机制为主&#xff0c;标记-清除和分代收集两种机制为辅的垃圾回收机制。 首先&#xff0c;需要搞清楚变量和对象的关系&#xff1a; * 变量&…

云原生时代 RocketMQ 运维管控的利器 - RocketMQ Operator

作者 | 刘睿、杜恒 导读&#xff1a;RocketMQ Operator 现已加入 OperatorHub&#xff0c;正式进入 Operator 社区。本文将从实践出发&#xff0c;结合案例来说明&#xff0c;如何通过 RocketMQ Operator 在 Kubernetes 上快速搭建一个 RocketMQ 集群&#xff0c;并提供一些 Ro…

Spring Security BadCredentialsException: Bad credentials问题解决

问题描述&#xff1a; org.springframework.security.authentication.BadCredentialsException: Bad credentials 问题分析&#xff1a; 1、数据库里面的密码没有加密&#xff0c;导致输入正确密码也匹配不上。 解决办法&#xff1a;使用PasswordEncoder先将当前密码加密&…

携程在港挂牌:两次疫情两次上市 穿越周期初心不灭

携程香港联合交易所上市庆祝仪式现场 2021年4月19日9点30分,携程集团正式在香港联合交易所上市&#xff0c;股份代号&#xff1a;9961.hk。这是继2003年在美国纳斯达克上市后&#xff0c;携程在香港的第二次上市。在上海市凌空SOHO携程总部大楼前&#xff0c;8位携程客人代表数…

淘宝直播在智能互动领域的探索及落地

简介&#xff1a; 随着带宽成本的降低和端上算力的提升&#xff0c;在直播、短视频中基于流的互动玩法也将越来越丰富&#xff1b;无论是基于人脸、手势、分割算法的智能化贴纸&#xff0c;还是结合算法的小游戏有了越来越好的舞台&#xff1b;业界短视频和直播主要针对的娱乐性…

基于实时计算Flink的机器学习算法平台及场景介绍

作者&#xff1a;高旸&#xff08;吾与&#xff09;&#xff0c;阿里巴巴高级技术专家 1. 前言 随着互联网“人口红利”的“消耗殆尽”&#xff0c;基于“T1”或者离线计算的机器学习平台及推荐系统转化率与效果日趋“平淡”。后疫情时代的新社会模式及经济形态必将催生出新的…

SpringCloud 应用在 Kubernetes 上的最佳实践 — 线上发布(可监控)

简介&#xff1a; 本篇是“SpringCloud 应用在 Kubernetes 上的最佳实践”系列文章的第六篇&#xff0c;主要介绍了如何保障生产环境服务稳定&#xff0c;做到随时发布&#xff0c;从而加快业务的迭代和上线速度。 文&#xff1a;骐羽 前言 在应用发布上线的时候我们最担心的…

mPaaS:全新移动开发平台,只为打造性能更优越的App

简介&#xff1a; 基于移动开发现状与技术演进预判&#xff0c;提供移动开发强力解决方案&#xff0c;洞察 mPaaS 如何帮助企业有效降低技术门槛&#xff0c;减少研发成本&#xff0c;搭建更稳定、更流畅的移动 App。 mPaaS 是源自于支付宝的移动开发平台&#xff0c;为移动开发…

德勤2021技术趋势:繁琐、点状的匠人AI时代将终结,MLOps时代来临

作者 | 宋慧 出品 | CSDN 头图 | 付费下载于视觉中国 德勤在近日发布《2021 年技术趋势》报告&#xff0c;这已经是德勤连续第十二年发布全球技术趋势报告。纵观今年的九大技术趋势&#xff0c;德勤给出的主题关键词是“韧性”&#xff0c;建议企业运用技术实现敏捷发展、构建…

Security RBAC 表结构+权限查询sql

文章目录1. 表结构2. 权限查询sql1. 表结构 /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Version : 80026Source Host : localhost:3306Source Schema : sys-adminTarget Server Type …

蚂蚁架构师郭援非:分布式数据库是金融机构数字化转型的最佳路径

简介&#xff1a; OceanBase立志于成为世界领先的企业级数据技术解决方案提供商。 2020年8月26-28日&#xff0c;在中科软科技举办的中国财险科技应用高峰论坛上&#xff0c;蚂蚁集团高级解决方案架构师郭援非发表了《OceanBase分布式关系数据库助力保险业务创新》的主题演讲&…

实锤!Python 真没你想的那么简单…

首先我不可否认&#xff0c;Python确实很“火”&#xff01;很多开发者都把它当做主语言或是第二语言。当做主语言原因很好理解&#xff0c;因为最近几年它在人工智能、数据分析、Web开发等众多领域都有着非常成熟的应用。当做第二语言&#xff0c;是因为用它来完成多线程、数据…

jdbcUrl is required with driverClassName错误解决

springboot 升级到2.0之后发现配置多数据源的时候报错&#xff1a; “jdbcUrl is required with driverClassName.”或者Cause: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.] with root cause 主要原因是在1.0 配置数据…