一.自助接入步骤。 

1.登录腾讯云开通人脸核身服务。 

 2.选择微信h5。

3.填写用户授权信息,选择对比源。

4.在调用实名核身鉴权接口时,必须传入认证人姓名和身份证号。

5.配置结果。

二.时序图

三.后端接口

 service

package com.ynfy.buss.exam.faceverify.service.impl;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.faceid.v20180301.FaceidClient;
import com.tencentcloudapi.faceid.v20180301.models.*;
import com.ynfy.buss.exam.faceverify.service.IFaceVerifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Objects;


/**
 * @Description: 人脸核验
 * @Author: yangfeng
 * @Date: 2024-04-01
 * @Version: V1.0
 */
@Slf4j
@Service
public class FaceVerifyServiceImpl implements IFaceVerifyService {

    @Value("${tencent.cloud.faceApi}")
    private String faceApi;

    @Value("${tencent.cloud.secretId}")
    private String secretId;

    @Value("${tencent.cloud.secretKey}")
    private String secretKey;

    @Value("${tencent.cloud.ruleId}")
    private String ruleId;

    @Value("${tencent.cloud.redirectUrl}")
    private String redirectUrl;

    /**
     * 实名核身鉴权
     *
     * @return
     */
    @Override
    public DetectAuthResponse detectAuth(String examId, String realName, String idCard, String imageBase64) {
        DetectAuthResponse resp = null;
        try {
            Credential cred = new Credential(secretId, secretKey);
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint(faceApi);
            httpProfile.setConnTimeout(10); // 请求连接超时时间,单位为秒(默认60秒)
            httpProfile.setWriteTimeout(10);  // 设置写入超时时间,单位为秒(默认0秒)
            httpProfile.setReadTimeout(10);
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            FaceidClient client = new FaceidClient(cred, "", clientProfile);
            DetectAuthRequest req = new DetectAuthRequest();
            req.setRuleId(ruleId);
            req.setIdCard(idCard);
            req.setName(realName);
            req.setImageBase64(imageBase64);
            req.setRedirectUrl(redirectUrl + examId + "&isNeedFaceDetect=" + true);
            resp = client.DetectAuth(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        return resp;
    }


    /**
     * 获取实名核身结果信息
     *
     * @param bizToken
     * @return
     */
    @Override
    public GetDetectInfoEnhancedResponse getDetectInfo(String bizToken) {
        GetDetectInfoEnhancedResponse resp = null;
        try {
            Credential cred = new Credential(secretId, secretKey);
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint(faceApi);
            httpProfile.setConnTimeout(10); // 请求连接超时时间,单位为秒(默认60秒)
            httpProfile.setWriteTimeout(10);  // 设置写入超时时间,单位为秒(默认0秒)
            httpProfile.setReadTimeout(10);
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            FaceidClient client = new FaceidClient(cred, "", clientProfile);
            GetDetectInfoEnhancedRequest req = new GetDetectInfoEnhancedRequest();
            req.setBizToken(bizToken);
            req.setInfoType("0");
            req.setRuleId(ruleId);
            resp = client.GetDetectInfoEnhanced(req);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        return resp;
    }

    /**
     * 实名核身是否通过
     *
     * @param bizToken
     * @return
     */
    @Override
    public boolean faceDetectIsPass(String bizToken) {
        GetDetectInfoEnhancedResponse resp = getDetectInfo(bizToken);
        if (!Objects.isNull(resp)) {
            DetectInfoText text = resp.getText();
            return !Objects.isNull(text) && text.getErrCode().intValue() == 0;
        }
        return false;
    }


}

 controller

package com.ynfy.app.api.v1.controller;

import com.ynfy.app.api.v1.annoation.IgnoreAuth;
import com.ynfy.buss.exam.faceverify.service.IFaceVerifyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.TokenUtil;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: 人脸核验(目前仅适用微信h5)
 * @Author: yangfeng
 * @Date: 2024-04-01
 * @Version: V1.0
 */
@Api(tags = "人脸核验")
@RestController
@RequestMapping("/api/v1/faceVerify")
@Slf4j
public class ApiFaceVerifyController extends ApiBaseController {
    @Autowired
    private IFaceVerifyService faceVerifyService;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 实名核身鉴权
     *
     * @return
     */
    @ApiOperation(value = "实名核身鉴权", notes = "实名核身鉴权")
    @GetMapping(value = "/detectAuth")
    public Result<?> detectAuth(@RequestParam String examId) {
        log.info("考试:{},实名核身鉴权开始...", examId);
        SysUser user = sysUserService.getUserByName(TokenUtil.getUserName(TokenUtil.getToken(request)));
        log.info("user:{}", user.toString());
        return Result.OK(faceVerifyService.detectAuth(examId, user.getRealname(), user.getIdCard(), user.getImageBase64()));
    }

    /**
     * 获取实名核身结果信息
     *
     * @param bizToken
     * @return
     */
    @IgnoreAuth
    @ApiOperation(value = "获取实名核身结果信息", notes = "获取实名核身结果信息")
    @GetMapping(value = "/getDetectInfo")
    public Result<?> getDetectInfo(@RequestParam String bizToken) {
        log.info("获取实名核身结果信息,bizToken:{}", bizToken);
        return Result.OK("", faceVerifyService.getDetectInfo(bizToken));
    }

    /**
     * 实名核身是否通过
     *
     * @param bizToken
     * @return
     */
    @IgnoreAuth
    @ApiOperation(value = "实名核身是否通过", notes = "实名核身是否通过")
    @GetMapping(value = "/faceDetectIsPass")
    public Result<?> faceDetectIsPass(@RequestParam String bizToken) {
        log.info("调用实名核身是否通过接口,bizToken:{}", bizToken);
        return Result.OK(faceVerifyService.faceDetectIsPass(bizToken));
    }

}

 四.h5前端。

点击“开始考试”后,读取本次考试 是否需要进行人脸核验。如果需要,调用实名核身鉴权,接口会返回用于发起核身流程的URL。

    async created() {
			this.initFormData();

			// #ifdef H5
			if (this.isNeedFaceDetect && JSON.parse(this.isNeedFaceDetect)) {
				//实名核身是否通过
				const data = await apiFaceDetectIsPass(this.bizToken)
				if (data) {
					//通过的话则加载考试信息
					this.loadExam()
				}
			}
			// #endif 
		},
        //开始考试
			async startExam() {
				//h5需要人脸核身验证后才可以开始
				// #ifdef H5
				//本考试是否支持人脸核身
				if (!!this.form.globalFaceEnable && !!this.form.faceDetectEnable) {
					const data = await apiDetectAuth(this.examId)
					window.location.href = data.url
					this.isNeedFaceDetect = true
				} else {
					this.loadExam()
				}
				// #endif 

				//非h5直接进入考试
				// #ifndef H5
				this.loadExam()
				// #endif 
			},

跳转url核验,核验完成后,会根据实名核身鉴权接口传入的RedirectUrl,

跳转前端页面,监听BizToken参数和自助传入的参数,获取核验结果。如果通过,则可以进行考试。

 五.效果。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐