0
点赞
收藏
分享

微信扫一扫

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

;

/**
* 合作方后台上送身份信息 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/35893
private 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​​

getAccessTokenTencent() {

// 从redis中获取accessTokenTencent
String 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_token
accessTokenTencent = 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

(String accessTokenTencent) {
// 从redis中获取nonceTicketTencent
String 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

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


计算签名

> 合作方上送身份信息计算签名
* 文档地址: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
*/
@Override
public TXH5IdentityInfoDTO sendH5IdentityInfoUserInfo(FaceDetectUserVO faceDetectUserVO) {
//获取accessToken
String accessToken = commonIdentityService.getAccessTokenTencent();
//获取signTicket
String 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

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

(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

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

(FaceDetectUserVO faceDetectUserVO) {
//随机生成32位唯一用户ID和订单ID
String userId = SignUtils.GenerateRandom32Number(32);
String orderNo = SignUtils.GenerateRandom32Number(32);
faceDetectUserVO.setOrderNo(orderNo);
faceDetectUserVO.setUserId(userId);
String requestUrl = "";
try {

//获取accessToken
String 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);

//获取nonceTicket
String 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人脸核身

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


AI 腾讯云人脸核身之独立H5接入_云计算_04

(String orderNo) {
//获取accessToken
String accessToken = commonIdentityService.getAccessTokenTencent();

//获取signTicket
String 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;
}


举报

相关推荐

0 条评论