• 人脸核身基础版 SDK 接入 > 合作方后台上送身份信息


    一、概述

    人脸识别,使用官方API:腾讯云人脸核身之独立H5接入。接口官方返回code = 0 表示成功,其他code码值均为对应码值信息,详见错误码。

    注意:
    1.合作方上送身份信息的计算签名参数与启动人脸核身计算签名参数不一致,有部分区别。
    2.wbappid = webankAppId = app_id

    二、实现流程
    2.1. 获取获取 access_token

    文档: https://cloud.tencent.com/document/product/1007/37304

    2.2. 获取 SIGN ticket

    文档: https://cloud.tencent.com/document/product/1007/37305

    2.3. 生成签名

    文档: https://cloud.tencent.com/document/product/1007/35866

    2.4. 上送身份信息

    文档: https://cloud.tencent.com/document/product/1007/35866

    2.5. 获取 NONCE ticket

    文档: https://cloud.tencent.com/document/product/1007/37306

    三、实战
    3.1. 获取获取 access_token

    app_id获取:https://cloud.tencent.com/document/product/1007/49634
    secret获取:https://cloud.tencent.com/document/product/1007/49634
    在这里插入图片描述

    @Autowired
        private RedisUtils redisUtils;
    
        @Value("${tencent-cloud.wbappid}")
        private String appId;
        @Value("${tencent-cloud.secret}")
        private String secret;
    
        /**
         * 获取 access_token
         * 文档: https://cloud.tencent.com/document/product/1007/37304
         *
         * @return
         */
        @Override
        public String 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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    3.2. 获取 SIGN ticket

    在这里插入图片描述

       /**
         * 获取 SIGN ticket
         * 请求地址: http://localhost:9900/getSignTicketTencent
         * 文档: https://cloud.tencent.com/document/product/1007/37305
         *
         * @param accessTokenTencent access_token
         * @return
         */
        @Override
        public String getSignTicketTencent(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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    3.3. 生成签名

    在这里插入图片描述

     /**
         * 合作方上送身份信息计算签名
         * API: https://cloud.tencent.com/document/product/1007/35866
         *
         * @param userId     用户唯一标识,同一个用户的 userId 请保持一致,我们会根据 userId 来做防重复点击优化
         * @param signTicket 合作伙伴服务端获取的 ticket,注意是 SIGN 类型
         * @return
         */
        @Override
        public String sign(String userId, String signTicket) {
    
            //为计算签名做准备
            List<String> list = new ArrayList<>();
            list.add(appId);
            list.add(userId);
            list.add(SignUtils.GenerateRandom32Number());
            list.add(TencentCloudConfig.VERSION);
            return SignUtils.getSign(list, signTicket);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    package com.gblfy.tencent.cloud.utils;
    
    import com.gblfy.tencent.cloud.result.GraceJSONResult;
    import com.google.common.base.Charsets;
    import com.google.common.hash.Hashing;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import org.springframework.util.CollectionUtils;
    
    import java.util.Collections;
    import java.util.List;
    import java.util.UUID;
    
    /**
     * Java 签名算法
     * 腾讯云文档: https://cloud.tencent.com/document/product/1007/37307
     *
     * @author gblfy
     * @Date 2022-09-06
     **/
    @Slf4j
    @Component
    public class SignUtils {
    
        //签名计算
        public static String getSign(List<String> values, String signTicket) {
            if (CollectionUtils.isEmpty(values)) {
                GraceJSONResult.errorMsg("签名计算 values is null");
            }
            // remove null
            values.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();
        }
    
        //生成32位随机数
        public static String GenerateRandom32Number() {
            return UUID.randomUUID().toString().replace("-", "");
        }
        // public static void main(String[] args) {
        //     System.out.println(UUID.randomUUID().toString().replace("-", "").length());
        //     System.out.println(UUID.randomUUID().toString().replace("-", ""));
        // }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    3.4. 上送身份信息

    在这里插入图片描述

     /**
         * 合作方后台上送身份信息
         *
         * @param faceDetectUserVO 身份信息
         * @return
         */
        @Override
        public GraceJSONResult sendIdentityInfoUserInfo(FaceDetectUserVO faceDetectUserVO) {
            //获取accessToken
            String accessToken = getAccessTokenTencent();
            //获取signTicket
            String signTicket = getSignTicketTencent(accessToken);
            //合作方上送计算签名
            String sign = sign(signTicket, faceDetectUserVO.getUserId());
            String orderNo = faceDetectUserVO.getOrderNo();
    
            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_FACEID_URL, orderNo);
            String jsonStr = HttpUtil.doPost(getFaceidUrl, JSON.toJSONString(param));
            log.info("返回报文;->{}", jsonStr);
    
            TXIdentityInfoDTO txIdentityInfoDTO = JSON.parseObject(jsonStr, TXIdentityInfoDTO.class);
            log.info("合作方上送身份信息接口返回:[{}]", txIdentityInfoDTO);
            return GraceJSONResult.ok(txIdentityInfoDTO);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    3.5. 获取 NONCE ticket

    在这里插入图片描述

     /**
         * 获取 NONCE ticket
         * 请求地址: http://localhost:9900/getNonceTicketTencent?userId=123456
         * 文档: https://cloud.tencent.com/document/product/1007/37306
         *
         * @param userId 当前使用用户的唯一标识,需合作伙伴自行定义
         * @return
         */
        @Override
        public GraceJSONResult getNonceTicketTencent(String userId) {
            // 从redis中获取nonceTicketTencent
            String nonceTicketTencent = redisUtils.get("nonceTicketTencent");
            log.info("获取redis中的nonceTicketTencent,为:[{}]", nonceTicketTencent);
    
            // 获取access_token
            String accessTokenTencent = getAccessTokenTencent();
    
            String nonceTicketValue = null;
            if (StringUtils.isEmpty(nonceTicketTencent)) {
                String nonceTicketUrl = String.format(TencentCloudConfig.NONCE_TICKET_URL, appId, accessTokenTencent, userId);
                String jsonStr = HttpUtil.doGet(nonceTicketUrl, null);
                log.info("返回报文;->{}", jsonStr);
    
                TicketDTO ticketDTO = JSON.parseObject(jsonStr, TicketDTO.class);
                if (!"0".equals(ticketDTO.getCode())) {
                    String msg = ticketDTO.getMsg();
                    log.error("获取腾讯NonceTicket信息错误,code:{},msg:{}", ticketDTO.getCode(), msg);
                    GraceJSONResult.errorMsg(msg);
                }
    
                /**
                 * 正确响应示例:
                 * {
                 *       "code": "0",
                 *       "msg": "请求成功",
                 *       "transactionTime": "20151022044027",
                 *       "tickets": [
                 *         {
                 *               "value": "ticket_string",
                 *               "expire_in": "120",
                 *               "expire_time": "20151022044027"
                 *         }
                 *     ]
                 * }
                 */
                nonceTicketValue = ticketDTO.getTickets().get(0).getValue();
    
                // 过期时间 默认120L  设置100L提前重新获取
                redisUtils.set("nonceTicketTencent", nonceTicketValue, 100L);
            }
    
            return GraceJSONResult.ok(nonceTicketValue);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    四、开源地址

    https://gitee.com/gblfy/tencent-cloud

  • 相关阅读:
    润和软件DAYU 200的OpenHarmony赋能之旅
    页面滚动组件
    无人机技术,无人机动力系统知识,电机、电调、桨叶技术详解
    野火FPGA进阶(2):基于I2C协议的EEPROM驱动控制
    java类和对象——static成员与代码块
    酷早报:10月20日全球Web3加密行业重大资讯大汇总
    命令行错误 D8016:卢友亮 ucos ii 在vs2019 编译报错
    IB经济与商业可以一起选吗?
    接口测试是什么?怎样做接口测试?(测试人必看,讲的超详细)
    TCMonodepth:Enforcing Temporal Consistency in Video Depth Estimation-论文阅读
  • 原文地址:https://blog.csdn.net/weixin_40816738/article/details/126744940