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

这篇具有很好参考价值的文章主要介绍了java腾讯云人脸核身移动浮层H5接入。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

腾讯云人脸核身文档

最近公司有业务需求,需要对企业微信中的小程序添加人脸识别功能,一般的人脸核身是对app中添加sdk完成的,考虑到业务需要,采用腾讯云的移动浮层H5接入,废话不多说,直接上代码。
java腾讯云人脸核身移动浮层H5接入,腾讯云,微信,云计算
这边,这3步已经满足了我们的需要。

1、配置文件

nonce是自定义的随机字符串,redirectUrl是验证成功后回调的页面

# 腾讯人脸识别配置
tencentFaceVerify:
  appId: ******
  appSecret: ***********************
  version: 1.0.0
  nonce: ************
  redirectUrl: https://*****/index

2、工具类



import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Base64;

public class Base64Util {

    private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    public Base64Util() {
    }

    public static String encode(String source) {
        if (!isEmpty(source)) {
            byte[] bytes = source.getBytes(DEFAULT_CHARSET);
            String asB64 = Base64.getEncoder().encodeToString(bytes);
            return asB64;
        } else {
            return source;
        }
    }

    public static String decode(String source) {
        if (!isEmpty(source)) {
            byte[] bytes = Base64.getDecoder().decode(source);
            String target = new String(bytes, DEFAULT_CHARSET);
            return target;
        } else {
            return source;
        }
    }

    private static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    /**
     * 对字节数组字符串进行Base64解码并生成图片
     * @param base64
     * @param path
     * @return
     */
    public static boolean base64ToImage(String base64, String path) {
        if (base64 == null) {
            return false;
        }

        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] bytes = decoder.decodeBuffer(base64);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }

            // 生成jpeg图片
            OutputStream out = new FileOutputStream(path);
            out.write(bytes);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 将一张网络图片转化成Base64字符串
     * @param imgURL
     * @return
     */
    public static String GetImageStrFromUrl(String imgURL) {
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try {
            // 创建URL
            URL url = new URL(imgURL);
            byte[] by = new byte[1024];
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            // 将内容读取内存中
            int len = -1;
            while ((len = is.read(by)) != -1) {
                data.write(by, 0, len);
            }
            // 关闭流
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data.toByteArray());
    }

}

package com.lynkco.lcem.util;

import java.text.SimpleDateFormat;
import java.util.UUID;

public class SerialUtil {

    private static final String DATE_FORMAT = "yyyyMMdd";

    private SerialUtil (){}

    public static String getBatchNo(String prefix) {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        StringBuffer batchNo = new StringBuffer(prefix);
        batchNo.append(sdf.format(System.currentTimeMillis()))
                .append((int)((Math.random()*9+1)*100000));
        return batchNo.toString();
    }

    public static String getUUID() {
        String uuid = UUID.randomUUID().toString();
        return uuid.replace("-", "");
    }


}

3、实体类

/**
 * @author :xuwei
 * @description:人脸入参,参考https://cloud.tencent.com/document/product/1007/61073
 * @date :2022/8/25 21:43
 */
@Data
@ApiModel
public class TencentFaceVerifyParam {

    @ApiModelProperty(name="sourcePhotoStr", value = "比对源照片")
    private String sourcePhotoStr;

    @ApiModelProperty(name="sourcePhotoType", value = "比对源照片类型参数值为1 时是:水纹正脸照 2时是:高清正脸照")
    private String sourcePhotoType;

    @ApiModelProperty(name="liveInterType", value = "参数值为1时,表示仅使用实时检测模式, " +
            "参数值非1或不入参,表示优先使用实时检测模式,如遇不兼容情况,自动降级为视频录制模式")
    private String liveInterType;
}


/**
 * @author :xuwei
 * @description:人脸入参,参考https://cloud.tencent.com/document/product/1007/61073
 * @date :2022/8/25 21:43
 */
@Data
@Builder
public class TencentFaceVerifyDto {
    private String appId;
    private String orderNo;
    private String userId;
    private String sourcePhotoStr;
    private String sourcePhotoType;
    private String liveInterType;
    private String version;
    private String sign;
    private String nonce;
    private String ticket;

}

/**
 * @author :xuwei
 * @description:人脸出参,参考https://cloud.tencent.com/document/product/1007/61073
 *              https://cloud.tencent.com/document/product/1007/61074
 * @date :2022/8/25 21:43
 */
@Data
public class TencentFaceVerifyResult {

    private String bizSeqNo;
    private String transactionTime;
    private String orderNo;
    private String faceId;
    private String optimalDomain;
    private String success;

    private String webankAppId;
    private String userId;
    private String version;
    private String nonce;
    private String sign;
    private String redirectUrl;
}

4、处理代码

controller


import com.lynkco.lcem.common.BaseResult;
import com.lynkco.lcem.common.config.LoginUserUtil;
import com.lynkco.lcem.dto.tencentFaceVerify.TencentFaceVerifyDto;
import com.lynkco.lcem.dto.tencentFaceVerify.TencentFaceVerifyParam;
import com.lynkco.lcem.dto.tencentFaceVerify.TencentFaceVerifyResult;
import com.lynkco.lcem.service.common.TencentFaceVerifyService;
import com.lynkco.lcem.util.ObjectUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * tencent实人认证
 *
 * @author xuwei
 * @title: TencentFaceVerifyController
 * @projectName lcem-server
 * @description: TODO
 * @date 2022/8/23 09:00
 */
@RefreshScope
@Slf4j
@RestController
@RequestMapping("/tencentFaceVerify")
@Api(value = "腾讯实人认证", tags = {"腾讯实人认证"})
public class TencentFaceVerifyController {

    @Autowired
    TencentFaceVerifyService tencentFaceVerifyService;


    @ApiOperation("上送身份信息")
    @PostMapping("/getAdvFaceId")
    public BaseResult getAdvFaceId(@RequestBody TencentFaceVerifyParam param, HttpServletRequest request) {
        String userId = LoginUserUtil.getCurrentUserId(request);
        TencentFaceVerifyDto dto = TencentFaceVerifyDto.builder().sourcePhotoStr(param.getSourcePhotoStr())
                .sourcePhotoType(param.getSourcePhotoType()).liveInterType(param.getLiveInterType())
                .userId(userId).build();
        String advFaceId = tencentFaceVerifyService.getAdvFaceId(dto);
        if (!ObjectUtils.isEmpty(advFaceId)){
            return BaseResult.ok(advFaceId);
        }
        return BaseResult.ok(null);
    }


}

service

public interface TencentFaceVerifyService {

   /**
    * 上送身份信息
    * @param param
    * @return
    */
   String getAdvFaceId(TencentFaceVerifyDto param);

}

serviceImpl



import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.lynkco.lcem.dto.tencentFaceVerify.TencentFaceVerifyDto;
import com.lynkco.lcem.dto.tencentFaceVerify.TencentFaceVerifyResult;
import com.lynkco.lcem.exception.BusinessException;
import com.lynkco.lcem.util.Base64Util;
import com.lynkco.lcem.util.HttpClientUtil;
import com.lynkco.lcem.util.SerialUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author :xuwei
 * @description:TODO
 * @date :2022/8/24 16:39
 */
@RefreshScope
@Service
public class TencentFaceVerifyServiceImpl implements TencentFaceVerifyService {

    @Value("${tencentFaceVerify.appId}")
    private String appId;
    @Value("${tencentFaceVerify.appSecret}")
    private String appSecret;
    @Value("${tencentFaceVerify.version}")
    private String version;
    @Value("${tencentFaceVerify.nonce}")
    private String nonce;
    @Value("${tencentFaceVerify.redirectUrl}")
    private String redirectUrl;


    /**
     * 上送身份信息
     * 参考文档:https://cloud.tencent.com/document/product/1007/61073
     * @param param
     * @return
     */
    @Override
    public String getAdvFaceId(TencentFaceVerifyDto param) {
        String accessToken = getAccessToken();
        String signTickets = getSignTickets(accessToken);

        String encode = Base64Util.GetImageStrFromUrl(param.getSourcePhotoStr());
        param.setSign(beforeSign(param.getUserId(), signTickets));
        param.setSourcePhotoStr(encode);
        param.setOrderNo(SerialUtil.getUUID());
        param.setAppId(appId);
        param.setVersion(version);
        param.setNonce(nonce);

        try {
            String jsonStr = JSONUtil.toJsonStr(param);
            String result = HttpClientUtil.doPostJson("https://kyc.qcloud.com/api/server/getAdvFaceId", jsonStr, null);
            Map<String, Object> resultMap = JSONObject.parseObject(result, Map.class);
            if (resultMap.get("code").equals("0")) {
                TencentFaceVerifyResult verifyResult = JSONObject.parseObject(resultMap.get("result").toString(), TencentFaceVerifyResult.class);
                verifyResult.setUserId(param.getUserId());
                //启动 H5 人脸核身地址
                String url = getUrl(param, accessToken, verifyResult);

                return url;
            }
        } catch (Exception e) {
            throw new BusinessException("后台上送身份信息失败:" + e.getMessage());
        }
        return null;
    }

    /**
     * 启动 H5 人脸核身地址
     * 参考文档:https://cloud.tencent.com/document/product/1007/61074
     * @param param
     * @param accessToken
     * @param verifyResult
     * @return
     * @throws UnsupportedEncodingException
     */
    private String getUrl(TencentFaceVerifyDto param, String accessToken, TencentFaceVerifyResult verifyResult) throws UnsupportedEncodingException {
        String nonceTickets = getNonceTickets(accessToken, param.getUserId());
        String sign = afterSign(verifyResult, nonceTickets);
        String encodeUrl = URLEncoder.encode(redirectUrl, "UTF-8");
        String url = "https://" + verifyResult.getOptimalDomain() + "/api/web/login?webankAppId=" + appId
                + "&version=" + version + "&nonce=" + nonce + "&orderNo=" + verifyResult.getOrderNo() +
                "&faceId=" + verifyResult.getFaceId() + "&url=" + encodeUrl + "&from=browser&userId=" + param.getUserId()
                + "&sign=" + sign + "&redirectType=1";
        return url;
    }


    /**
     * 获取 Access Token
     * 参考文档:https://cloud.tencent.com/document/product/1007/37304
     * @return
     */
    public String getAccessToken() {
        Map<String, String> map = new HashMap<>();
        map.put("app_id", appId);
        map.put("secret", appSecret);
        map.put("grant_type", "client_credential");
        map.put("version", version);

        String result = HttpClientUtil.doGet("https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/access_token", map);
        Map<String, Object> resultMap = JSONObject.parseObject(result, Map.class);
        if (resultMap.get("code").equals("0")) {
            Object access_token = resultMap.get("access_token");
            return access_token.toString();
        }
        return null;
    }

    /**
     * 获取 SIGN ticket
     * 参考文档:https://cloud.tencent.com/document/product/1007/37305
     * @param accessToken
     * @return
     */
    public String getSignTickets(String accessToken) {
        Map<String, String> map = new HashMap<>();
        map.put("app_id", appId);
        map.put("access_token", accessToken);
        map.put("type", "SIGN");
        map.put("version", version);

        String result = HttpClientUtil.doGet("https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket", map);
        Map<String, Object> resultMap = JSONObject.parseObject(result, Map.class);
        if (resultMap.get("code").equals("0")) {
            List<Map> tickets = JSONObject.parseArray(resultMap.get("tickets").toString(), Map.class);
            Object ticket = tickets.get(0).get("value");
            return ticket.toString();
        }
        return null;
    }

    /**
     * 获取 NONCE ticket
     * 参考文档:https://cloud.tencent.com/document/product/1007/37306
     * @param accessToken
     * @param userId
     * @return
     */
    public String getNonceTickets(String accessToken, String userId) {
        Map<String, String> map = new HashMap<>();
        map.put("app_id", appId);
        map.put("access_token", accessToken);
        map.put("type", "NONCE");
        map.put("version", version);
        map.put("user_id", userId);

        String result = HttpClientUtil.doGet("https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket", map);
        Map<String, Object> resultMap = JSONObject.parseObject(result, Map.class);
        if (resultMap.get("code").equals("0")) {
            List<Map> tickets = JSONObject.parseArray(resultMap.get("tickets").toString(), Map.class);
            Object ticket = tickets.get(0).get("value");
            return ticket.toString();
        }
        return null;
    }

    /**
     * 启动 H5 人脸核身所需签名
     * @param verifyResult
     * @param ticket
     * @return
     */
    public String afterSign(TencentFaceVerifyResult verifyResult, String ticket) {
        List<String> values = new ArrayList<>();
        values.add(version);
        values.add(verifyResult.getOrderNo());
        values.add(appId);
        values.add(verifyResult.getFaceId());
        values.add(nonce);
        values.add(verifyResult.getUserId());

        return sign(values, ticket);
    }

    /**
     * 后台上送身份信息所需签名
     * @param userId
     * @param ticket
     * @return
     */
    public String beforeSign(String userId, String ticket) {
        List<String> values = new ArrayList<>();
        values.add(version);
        values.add(appId);
        values.add(nonce);
        values.add(userId);
        return sign(values, ticket);
    }

    /**
     * 获取签名 参考文档 https://cloud.tencent.com/document/product/1007/57640
     * @param values
     * @param ticket
     * @return
     */
    public static String sign(List<String> values, String ticket) {
        if (values == null) {
            throw new NullPointerException("values is null");
        }
        values.removeAll(Collections.singleton(null));
        values.add(ticket);
        java.util.Collections.sort(values);
        StringBuilder sb = new StringBuilder();
        for (String s : values) {
            sb.append(s);
        }

        return Hashing.sha1().hashString(sb,
                Charsets.UTF_8).toString().toUpperCase();
    }


}

在获取启动 H5 人脸核身地址时,将地址返回给前端,让他直接调就行。或许自己可以直接在浏览器打开那个地址,如果成功的话,会调到腾讯云的人脸核身页面。
这里用来比对的原图片是网络图片,如果是本地图片的话,直接将本地图片base64后encode就行。另外,回调的地址也要encode一下。不然会有40010错误码出现。文章来源地址https://www.toymoban.com/news/detail-621451.html

到了这里,关于java腾讯云人脸核身移动浮层H5接入的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序实名认证接口_人脸核身接口整理

    一、微信小程序实名认证接口_人脸核身接口整理 开场一个字: 悲观。目前实名接口,人脸识别接口开放度不高。“实名信息授权”已经回收。 二、人脸核身接口   1.使用条件 需要现申请通过才能使用。 目前开放的分类不多,并且还需要行业资质。 2.详细使用官方文档 微信

    2024年02月09日
    浏览(45)
  • 移动端Web接入腾讯云TRTC实践(React+TS)

    实时音视频服务在项目中出现的频率越来越高的,自己写webRTC的成本相对腾讯云的TRTC-SDK要多大得多,最近公司项目移动端和PC端Web(React+TS)小程序(Taro)中都有使用到,这里针对移动端web做实时通话做个记录与大家交流下 相信准备接入或者已经在接入TRTC的小伙伴是看过文档

    2023年04月08日
    浏览(35)
  • 微信小程序接入腾讯云天御验证码

    腾讯云新一代行为验证码(Captcha),基于十道安全防护策略,为网页、APP、小程序开发者打造立体、全面的人机验证。在保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。 根据 腾讯云官方文档,在 验证码控制台 完成

    2024年02月14日
    浏览(45)
  • uniapp移动端——企业微信H5调用jssdk实现扫一扫,通过weixin-java-cp获取ticket签名,配置config

    背景: 使用企业微信开发扫一扫功能 可信域名验证  (1)企业微信的可信域名需要和企业微信的备案主体一致。 域名备案主体可通过站长工具查看域名备案主体。https://icp.chinaz.com/ 企业微信备案主体可以咨询管理员 (2)通过nginx配置域名归属验证txt文件 具体操作详见: htt

    2024年01月25日
    浏览(40)
  • H5接入微信公众号方法(超详细)

    微信官方文档 注意: 在微信开发者工具中调试,必须先成为公众号开发者,可以在微信公众号后台进行配置 位置: 公众号后台 设置与开发 开发者工具 web开发者工具 绑定微信开发者微信号(必须先关注此公众号才能成为开发者) 1. 接口配置信息 此处可不填写,这个地方的

    2024年02月04日
    浏览(49)
  • H5接入支付流程-微信支付&支付宝支付

    H5对接微信支付和支付宝支付,app无法发版,需要支持在app内和浏览器内同时使用。 于是借此机会对前端接入对第三方支付进行了调研,本次只讨论微信支付,和支付宝支付。 文档地址:微信支付 微信支付方式主要包括,对普通商家主要提供以下7种方式 付款码支付:比如大

    2024年02月19日
    浏览(55)
  • 〔支付接入〕微信的 h5 支付和 jsapi 支付

    申请地址: https://pay.weixin.qq.com/ 如果你还没有微信商户号,请点击上面的链接进行申请,如果已经有了,可以跳过这一步 首先点击 账户中心 ▶ API安全 ▶ 申请API证书 申请详细步骤: https://kf.qq.com/faq/161222NneAJf161222U7fARv.html 首先点击 账户中心 ▶ API安全 ▶ 设置APIv3密钥 ▶

    2024年02月13日
    浏览(52)
  • h5 小程序 公众号 接入微信支付开发

    ps:一般公司开发不需要确认 流程:下单-调起支付-返回结果跳回本页面 开发准备: 1: 配置并授权项目地址(地址需要是完整的)(配置的是点击支付调起微信的那个本项目地址) 2: 获取code(为获取openid做准备) window.location.href= = \\\'https://open.weixin.qq.com/connect/oauth2/authorize?

    2024年02月15日
    浏览(65)
  • 移动端h5页面微信一键登录

    在移动端的 H5 页面中,微信一键登录是一种常见的方式,可以方便地让用户使用已有的微信账号进行登录,并且提高用户的使用效率和体验。具体实现方法如下: 前端 code 获取到的数据需要传给后端进行验证,获取 openid 和 access_token。可以使用 urllib 库向微信服务器发送请求

    2024年02月12日
    浏览(40)
  • H5接入到微信小程序或者微信浏览器打开相机界面会白屏刷新

    最近开发的一个需求是H5项目,并嵌入到小程序中,其中有模块用到了拍照功能。 前端同事们开发这个功能嵌入到小程序后会有bug,只要打开相机拍照后返回界面,界面会白屏刷新并且返回到了上一级,前端同事查询微信论坛或者其他地方的问答都说是手机内存不足或者运行

    2024年02月04日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包