|
@@ -0,0 +1,634 @@
|
|
|
+package com.ruoyi.common.utils;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Author: tjf
|
|
|
+ * @Date: 2024/4/17 9:35
|
|
|
+ * @Describe:
|
|
|
+ */
|
|
|
+
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.aliyun.cloudauth20190307.Client;
|
|
|
+import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest;
|
|
|
+import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponse;
|
|
|
+import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponseBody;
|
|
|
+import com.aliyun.teaopenapi.models.Config;
|
|
|
+import com.aliyun.teautil.models.RuntimeOptions;
|
|
|
+import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
+import com.ruoyi.common.core.domain.SysUserIdcardVo;
|
|
|
+
|
|
|
+import javax.crypto.Cipher;
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+import static com.ruoyi.common.constant.Constants.BACK;
|
|
|
+import static com.ruoyi.common.constant.Constants.FRONT;
|
|
|
+
|
|
|
+public class IdCardUtil {
|
|
|
+ /**
|
|
|
+ * 重要提示代码中所需工具类
|
|
|
+ * FileUtil,HttpUtil请从
|
|
|
+ * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
|
|
|
+ * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
|
|
|
+ * 下载
|
|
|
+ * <p>
|
|
|
+ * https://cloud.baidu.com/doc/OCR/s/rk3h7xzck 文档地址
|
|
|
+ */
|
|
|
+
|
|
|
+ // aes key 从console控制台获取 身份证识别使用
|
|
|
+ static String aesKey = "ce539dc069ad0908";
|
|
|
+
|
|
|
+ static byte[] originAesKey = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 身份证识别
|
|
|
+ * {
|
|
|
+ * "log_id": "1559208562721579319",
|
|
|
+ * "direction": 0,
|
|
|
+ * "image_status": "normal",
|
|
|
+ * "photo": "/9j/4AAQSkZJRgABA......",
|
|
|
+ * "photo_location": {
|
|
|
+ * "width": 1189,
|
|
|
+ * "top": 638,
|
|
|
+ * "left": 2248,
|
|
|
+ * "height": 1483
|
|
|
+ * },
|
|
|
+ * "card_image": "/9j/4AAQSkZJRgABA......",
|
|
|
+ * "card_location": {
|
|
|
+ * "top": 328,
|
|
|
+ * "left": 275,
|
|
|
+ * "width": 1329,
|
|
|
+ * "height": 571
|
|
|
+ * },
|
|
|
+ * "words_result": {
|
|
|
+ * "住址": {
|
|
|
+ * "location": {
|
|
|
+ * "left": 267,
|
|
|
+ * "top": 453,
|
|
|
+ * "width": 459,
|
|
|
+ * "height": 99
|
|
|
+ * },
|
|
|
+ * "words": "南京市江宁区弘景大道3889号"
|
|
|
+ * },
|
|
|
+ * "公民身份号码": {
|
|
|
+ * "location": {
|
|
|
+ * "left": 443,
|
|
|
+ * "top": 681,
|
|
|
+ * "width": 589,
|
|
|
+ * "height": 45
|
|
|
+ * },
|
|
|
+ * "words": "330881199904173914"
|
|
|
+ * },
|
|
|
+ * "出生": {
|
|
|
+ * "location": {
|
|
|
+ * "left": 270,
|
|
|
+ * "top": 355,
|
|
|
+ * "width": 357,
|
|
|
+ * "height": 45
|
|
|
+ * },
|
|
|
+ * "words": "19990417"
|
|
|
+ * },
|
|
|
+ * "姓名": {
|
|
|
+ * "location": {
|
|
|
+ * "left": 267,
|
|
|
+ * "top": 176,
|
|
|
+ * "width": 152,
|
|
|
+ * "height": 50
|
|
|
+ * },
|
|
|
+ * "words": "伍云龙"
|
|
|
+ * },
|
|
|
+ * "性别": {
|
|
|
+ * "location": {
|
|
|
+ * "left": 269,
|
|
|
+ * "top": 262,
|
|
|
+ * "width": 33,
|
|
|
+ * "height": 52
|
|
|
+ * },
|
|
|
+ * "words": "男"
|
|
|
+ * },
|
|
|
+ * "民族": {
|
|
|
+ * "location": {
|
|
|
+ * "left": 492,
|
|
|
+ * "top": 279,
|
|
|
+ * "width": 30,
|
|
|
+ * "height": 37
|
|
|
+ * },
|
|
|
+ * "words": "汉"
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "words_result_num": 6
|
|
|
+ * }
|
|
|
+ * <p>
|
|
|
+ * <p>
|
|
|
+ * {
|
|
|
+ * "words_result": {
|
|
|
+ * "失效日期": {
|
|
|
+ * "words": "20390711",
|
|
|
+ * "location": {
|
|
|
+ * "top": 445,
|
|
|
+ * "left": 523,
|
|
|
+ * "width": 153,
|
|
|
+ * "height": 38
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "签发机关": {
|
|
|
+ * "words": "陆丰市公安局",
|
|
|
+ * "location": {
|
|
|
+ * "top": 377,
|
|
|
+ * "left": 339,
|
|
|
+ * "width": 195,
|
|
|
+ * "height": 38
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "签发日期": {
|
|
|
+ * "words": "20190606",
|
|
|
+ * "location": {
|
|
|
+ * "top": 445,
|
|
|
+ * "left": 343,
|
|
|
+ * "width": 152,
|
|
|
+ * "height": 38
|
|
|
+ * }
|
|
|
+ * }
|
|
|
+ * },
|
|
|
+ * "log_id": "1559208562721579328",
|
|
|
+ * "words_result_num": 3,
|
|
|
+ * "error_code": 0,
|
|
|
+ * "image_status": "normal"
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static AjaxResult idCard(String image, String idCardSide) {
|
|
|
+ try {
|
|
|
+ // 文件路径
|
|
|
+ byte[] imgData = FileUtil.readFileByBytes(image);
|
|
|
+
|
|
|
+ String imgStr = encryptImg(aesKey, imgData);
|
|
|
+
|
|
|
+ String imgParam = URLEncoder.encode(imgStr, "UTF-8");
|
|
|
+ String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
|
|
|
+ //-front:身份证含照片的一面
|
|
|
+ //-back:身份证带国徽的一面
|
|
|
+ //自动检测身份证正反面,如果传参指定方向与图片相反,支持正常识别,返回参数image_status字段为"reversed_side"
|
|
|
+ String param = "id_card_side=" + idCardSide +
|
|
|
+ "&image=" + imgParam +
|
|
|
+ "&AESEncry=" + true;
|
|
|
+ String accessToken = getAccessToken("TvvuZOOh7MgnlDFnw11ln67n", "CY47OI0eKAzYBD2LO55SM3OITzsyq6DK");
|
|
|
+ String encryptResult = HttpUtils.post(url, accessToken, param);
|
|
|
+ String decryptResult = parseResult(encryptResult);
|
|
|
+ JSONObject jsonObject = JSON.parseObject(decryptResult);
|
|
|
+ String wordsResult = jsonObject.getString("words_result");
|
|
|
+ Map<String, Object> map = new HashMap<>(3);
|
|
|
+ if (StringUtils.isNotEmpty(wordsResult)) {
|
|
|
+ JSONObject jsonObjectWordsResult = JSON.parseObject(wordsResult);
|
|
|
+ if (FRONT.equals(idCardSide)) {
|
|
|
+ String name = JSON.parseObject(jsonObjectWordsResult.getString("姓名")).getString("words");
|
|
|
+ String address = JSON.parseObject(jsonObjectWordsResult.getString("住址")).getString("words");
|
|
|
+ String idCard = JSON.parseObject(jsonObjectWordsResult.getString("公民身份号码")).getString("words");
|
|
|
+ map.put("realName", name);
|
|
|
+ map.put("address", address);
|
|
|
+ map.put("idCard", idCard);
|
|
|
+ } else if (BACK.equals(idCardSide)) {
|
|
|
+ String date = JSON.parseObject(jsonObjectWordsResult.getString("失效日期")).getString("words");
|
|
|
+ map.put("expirationDate", date);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return AjaxResult.success(map);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return AjaxResult.error();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加密图片
|
|
|
+ *
|
|
|
+ * @param aesKey
|
|
|
+ * @param imgData
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private static String encryptImg(String aesKey, byte[] imgData) throws Exception {
|
|
|
+ originAesKey = AesKeyUtil.parseAesKey(aesKey);
|
|
|
+ byte[] encImgBytes = AesUtil.encrypt(imgData, originAesKey);
|
|
|
+ String imgStr = Base64Util.encodeBase64(encImgBytes);
|
|
|
+ return imgStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解密结果
|
|
|
+ *
|
|
|
+ * @param encryptResult
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private static String parseResult(String encryptResult) throws Exception {
|
|
|
+ JSONObject obj = JSONObject.parseObject(encryptResult);
|
|
|
+ String result = obj.getString("result");
|
|
|
+ byte[] arr = Base64Util.decodeBase64(result);
|
|
|
+ String decryptResult = new String(AesUtil.decrypt(arr, originAesKey));
|
|
|
+ return decryptResult;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ static class AesKeyUtil {
|
|
|
+ private static final String HEX = "0123456789abcdef";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获得原生的128位的aeskey
|
|
|
+ * 因为一个byte位8位最后生成的byte数组长度为16
|
|
|
+ * <p>
|
|
|
+ * 16 * 8 = 128
|
|
|
+ *
|
|
|
+ * @param hex
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static byte[] parseAesKey(String hex) throws Exception {
|
|
|
+ char[] data = hex.toCharArray();
|
|
|
+ if (data.length != 16) {
|
|
|
+ throw new Exception(" ase key illegal ");
|
|
|
+ }
|
|
|
+ return decode(hex.toCharArray());
|
|
|
+ }
|
|
|
+
|
|
|
+ private static byte[] decode(char[] data) throws IllegalArgumentException {
|
|
|
+ int len = data.length;
|
|
|
+
|
|
|
+ byte[] out = new byte[len];
|
|
|
+
|
|
|
+ for (int i = 0; i < len; i++) {
|
|
|
+ int f = toDigit(data[i]);
|
|
|
+ out[i] = (byte) (f);
|
|
|
+ }
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int toDigit(char ch) {
|
|
|
+ return HEX.indexOf(ch);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static class AesUtil {
|
|
|
+
|
|
|
+ private static final String ALGORITHM = "AES";
|
|
|
+
|
|
|
+ private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * aes 加密
|
|
|
+ */
|
|
|
+ private static byte[] encrypt(byte[] src, byte[] aesKey) throws Exception {
|
|
|
+ Cipher cipher = getCipher(aesKey, Cipher.ENCRYPT_MODE);
|
|
|
+ byte[] ret = cipher.doFinal(src);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * aes 解密
|
|
|
+ */
|
|
|
+ public static byte[] decrypt(byte[] src, byte[] aesKey) throws Exception {
|
|
|
+ Cipher cipher = getCipher(aesKey, Cipher.DECRYPT_MODE);
|
|
|
+ byte[] original = cipher.doFinal(src);
|
|
|
+ return original;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Cipher getCipher(byte[] aesKey, int mode) throws Exception {
|
|
|
+ SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, ALGORITHM);
|
|
|
+ Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
|
|
|
+ cipher.init(mode, secretKeySpec);
|
|
|
+ return cipher;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static class Base64Util {
|
|
|
+
|
|
|
+ private static Base64.Encoder ENCODER = Base64.getEncoder();
|
|
|
+
|
|
|
+ // base64 加密
|
|
|
+ private static Base64.Decoder DECODER = Base64.getDecoder();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * base64加密
|
|
|
+ *
|
|
|
+ * @param arr
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static String encodeBase64(byte[] arr) {
|
|
|
+ String base64 = null;
|
|
|
+ try {
|
|
|
+ base64 = ENCODER.encodeToString(arr);
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ return base64;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * base64解密
|
|
|
+ *
|
|
|
+ * @param str
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static byte[] decodeBase64(String str) {
|
|
|
+ byte[] encodeBase64 = new byte[0];
|
|
|
+ try {
|
|
|
+ encodeBase64 = DECODER.decode(str);
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ return encodeBase64;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 人脸识别
|
|
|
+ *
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static AjaxResult sample(SysUserIdcardVo sysUserIdcardVo) {
|
|
|
+ String image = sysUserIdcardVo.getImage();
|
|
|
+ String idCardNumber = sysUserIdcardVo.getIdCard();
|
|
|
+ String name = sysUserIdcardVo.getRealName();
|
|
|
+ if (StringUtils.isEmpty(image) || StringUtils.isEmpty(idCardNumber) || StringUtils.isEmpty(name)) {
|
|
|
+ return AjaxResult.error("参数不完整");
|
|
|
+ }
|
|
|
+ // image 可以通过 getFileContentAsBase64("C:\fakepath\1675840208844.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
|
|
|
+ HashMap<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("access_token", getAccessToken("OmTDmo9hv4wll1ReYiRNJEfz", "vqnio9p7C17nbrkVar0MrHU4KOz2OXOr"));
|
|
|
+ paramMap.put("image", getFileContentAsBase64(image, false));
|
|
|
+ paramMap.put("image_type", "BASE64");
|
|
|
+ paramMap.put("id_card_number", idCardNumber);
|
|
|
+ paramMap.put("name", name);
|
|
|
+ paramMap.put("spoofing_control", "NORMAL");
|
|
|
+ paramMap.put("quality_control", "NORMAL");
|
|
|
+ //返回值
|
|
|
+ String post = HttpUtil.post("https://aip.baidubce.com/rest/2.0/face/v4/mingjing/verify", paramMap);
|
|
|
+ /**
|
|
|
+ * {
|
|
|
+ * "log_id": 1370579072568000512,
|
|
|
+ * "result": {
|
|
|
+ * "score": 40.884,
|
|
|
+ * "verify_status": 0
|
|
|
+ * },
|
|
|
+ * "dec_image": "/9j/4AAQSkZJRgABAgAAAQABAAD",
|
|
|
+ * "risk_level": "3",
|
|
|
+ * "risk_tag": [
|
|
|
+ * "若判断为有风险,则会有风险标签json 数组告知风险类型,如:general_inject"
|
|
|
+ * ]
|
|
|
+ * }
|
|
|
+ */
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(post);
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ return AjaxResult.success(map);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取文件base64编码
|
|
|
+ *
|
|
|
+ * @param path 文件路径
|
|
|
+ * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
|
|
|
+ * @return base64编码信息,不带文件头
|
|
|
+ * @throws IOException IO异常
|
|
|
+ */
|
|
|
+ static String getFileContentAsBase64(String path, boolean urlEncode) {
|
|
|
+ byte[] b = new byte[0];
|
|
|
+ try {
|
|
|
+ b = Files.readAllBytes(Paths.get(path));
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ String base64 = Base64.getEncoder().encodeToString(b);
|
|
|
+ if (urlEncode) {
|
|
|
+ try {
|
|
|
+ base64 = URLEncoder.encode(base64, "utf-8");
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return base64;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取百度开放平台的AccessToken
|
|
|
+ * client_id: 必须参数,应用的API Key;
|
|
|
+ * client_secret: 必须参数,应用的Secret Key;不同的功能不同
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String getAccessToken(String apiKey, String secretKey) {
|
|
|
+ String url = "https://aip.baidubce.com/oauth/2.0/token";
|
|
|
+ /**
|
|
|
+ *grant_type: 必须参数,固定为client_credentials;
|
|
|
+ *client_id: 必须参数,应用的API Key;
|
|
|
+ *client_secret: 必须参数,应用的Secret Key;
|
|
|
+ */
|
|
|
+ HashMap<String, Object> paramMap = new HashMap<>(3);
|
|
|
+ paramMap.put("grant_type", "client_credentials");
|
|
|
+ paramMap.put("client_id", apiKey);
|
|
|
+ paramMap.put("client_secret", secretKey);
|
|
|
+ String post = cn.hutool.http.HttpUtil.post(url, paramMap);
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(post);
|
|
|
+ String accessToken = jsonObject.getString("access_token");
|
|
|
+ return accessToken;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 人脸识别阿里云金融级实人认证
|
|
|
+ *
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static AjaxResult ocrSampleAliYun(SysUserIdcardVo sysUserIdcardVo) {
|
|
|
+
|
|
|
+ return AjaxResult.success(initFaceVerify(sysUserIdcardVo));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 阿里云调用人脸识别
|
|
|
+ * 每次开始认证前通过本接口获取CertifyId,用来串联认证请求中的各个接口。
|
|
|
+ */
|
|
|
+ public static Object initFaceVerify(SysUserIdcardVo sysUserIdcardVo) {
|
|
|
+ InitFaceVerifyRequest request = new InitFaceVerifyRequest();
|
|
|
+ // 请输入场景ID+L。1000009979场景id固定值
|
|
|
+ request.setSceneId(1000009979L);
|
|
|
+ // 设置商户请求的唯一标识。
|
|
|
+ request.setOuterOrderNo(UUID.randomUUID().toString().replaceAll("-", ""));
|
|
|
+ // 认证方案。
|
|
|
+ request.setProductCode("ID_PRO");
|
|
|
+ // 模式。要进行活体检测的类型。取值:
|
|
|
+ //LIVENESS(默认):眨眼动作活体检测。
|
|
|
+ //
|
|
|
+ //PHOTINUS_LIVENESS:眨眼动作活体+炫彩活体双重检测。
|
|
|
+ //
|
|
|
+ //MULTI_ACTION:多动作活体检测。当前为眨眼+任意摇头检测。
|
|
|
+ request.setModel("PHOTINUS_LIVENESS");
|
|
|
+ //不同证件类型,取值均为IDENTITY_CARD
|
|
|
+ request.setCertType("IDENTITY_CARD");
|
|
|
+ //您的终端用户的真实姓名
|
|
|
+ request.setCertName(sysUserIdcardVo.getRealName());
|
|
|
+ //您的终端用户的证件号码。
|
|
|
+ request.setCertNo(sysUserIdcardVo.getIdCard());
|
|
|
+ // MetaInfo环境参数。
|
|
|
+ request.setMetaInfo(sysUserIdcardVo.getMetaInfo());
|
|
|
+ //业务页面回跳的目标地址。
|
|
|
+ String returnUrl = sysUserIdcardVo.getReturnUrl();
|
|
|
+ if (StringUtils.isNotEmpty(returnUrl)) {
|
|
|
+ //H5的model不一样
|
|
|
+ request.setModel("MULTI_ACTION");
|
|
|
+ request.setReturnUrl(returnUrl);
|
|
|
+ }
|
|
|
+ //request.setMobile("130xxxxxxxx");
|
|
|
+ //request.setIp("114.xxx.xxx.xxx");
|
|
|
+ //request.setUserId("12345xxxx");
|
|
|
+ //request.setCallbackUrl("https://www.aliyundoc.com");
|
|
|
+ //request.setCallbackToken("xxxxx");
|
|
|
+ // 如需开启个人信息加密传输。
|
|
|
+ //request.setEncryptType("SM2");
|
|
|
+ //request.setCertName("BCRD/7ZkNy7Q*****M1BMBezZe8GaYHrLwyJv558w==");
|
|
|
+ //request.setCertNo("BMjsstxK3S4b1YH*****Pet8ECObfxmLN92SLsNg==");
|
|
|
+
|
|
|
+ // 推荐,支持服务路由。
|
|
|
+ InitFaceVerifyResponse response = initFaceVerifyAutoRoute(request);
|
|
|
+
|
|
|
+ // 不支持服务自动路由。
|
|
|
+ //InitFaceVerifyResponse response = initFaceVerify("cloudauth.cn-shanghai.aliyuncs.com", request);
|
|
|
+
|
|
|
+ response.getBody().getRequestId();
|
|
|
+ String certifyId = response.getBody().getResultObject().getCertifyId();
|
|
|
+
|
|
|
+ InitFaceVerifyResponseBody.InitFaceVerifyResponseBodyResultObject resultObject = response.getBody().getResultObject();
|
|
|
+
|
|
|
+ System.out.println(response.getBody().getRequestId());
|
|
|
+ System.out.println("人脸识别跳转URL"+resultObject.getCertifyUrl());
|
|
|
+ System.out.println(response.getBody().getCode());
|
|
|
+ System.out.println(response.getBody().getMessage());
|
|
|
+ System.out.println(response.getBody().getResultObject() == null ? null
|
|
|
+ : response.getBody().getResultObject().getCertifyId());
|
|
|
+ return resultObject;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 阿里云调用人脸识别H5
|
|
|
+ * 每次开始认证前通过本接口获取CertifyId,用来串联认证请求中的各个接口。
|
|
|
+ */
|
|
|
+ public static InitFaceVerifyResponseBody.InitFaceVerifyResponseBodyResultObject initFaceVerifyH5(SysUserIdcardVo sysUserIdcardVo) {
|
|
|
+ InitFaceVerifyRequest request = new InitFaceVerifyRequest();
|
|
|
+ // 请输入场景ID+L。1000009979场景id固定值
|
|
|
+ request.setSceneId(1000009979L);
|
|
|
+ // 设置商户请求的唯一标识。
|
|
|
+ request.setOuterOrderNo(UUID.randomUUID().toString().replaceAll("-", ""));
|
|
|
+ // 认证方案。
|
|
|
+ request.setProductCode("ID_PRO");
|
|
|
+ // 模式。要进行活体检测的类型。取值:
|
|
|
+ //LIVENESS(默认):眨眼动作活体检测。
|
|
|
+ //
|
|
|
+ //PHOTINUS_LIVENESS:眨眼动作活体+炫彩活体双重检测。
|
|
|
+ //
|
|
|
+ //MULTI_ACTION:多动作活体检测。当前为眨眼+任意摇头检测。
|
|
|
+ request.setModel("PHOTINUS_LIVENESS");
|
|
|
+ //不同证件类型,取值均为IDENTITY_CARD
|
|
|
+ request.setCertType("IDENTITY_CARD");
|
|
|
+ //您的终端用户的真实姓名
|
|
|
+ request.setCertName(sysUserIdcardVo.getRealName());
|
|
|
+ //您的终端用户的证件号码。
|
|
|
+ request.setCertNo(sysUserIdcardVo.getIdCard());
|
|
|
+ // MetaInfo环境参数。
|
|
|
+ request.setMetaInfo(sysUserIdcardVo.getMetaInfo());
|
|
|
+ request.setCertifyUrlStyle("L");
|
|
|
+ //业务页面回跳的目标地址。
|
|
|
+ String returnUrl = sysUserIdcardVo.getReturnUrl();
|
|
|
+ if (StringUtils.isNotEmpty(returnUrl)) {
|
|
|
+ //H5的model不一样
|
|
|
+ request.setModel("MULTI_ACTION");
|
|
|
+ request.setReturnUrl(returnUrl);
|
|
|
+ }
|
|
|
+ //request.setMobile("130xxxxxxxx");
|
|
|
+ //request.setIp("114.xxx.xxx.xxx");
|
|
|
+ //request.setUserId("12345xxxx");
|
|
|
+ //request.setCallbackUrl("https://www.aliyundoc.com");
|
|
|
+ //request.setCallbackToken("xxxxx");
|
|
|
+ // 如需开启个人信息加密传输。
|
|
|
+ //request.setEncryptType("SM2");
|
|
|
+ //request.setCertName("BCRD/7ZkNy7Q*****M1BMBezZe8GaYHrLwyJv558w==");
|
|
|
+ //request.setCertNo("BMjsstxK3S4b1YH*****Pet8ECObfxmLN92SLsNg==");
|
|
|
+
|
|
|
+ // 推荐,支持服务路由。
|
|
|
+ InitFaceVerifyResponse response = initFaceVerifyAutoRoute(request);
|
|
|
+
|
|
|
+ // 不支持服务自动路由。
|
|
|
+ //InitFaceVerifyResponse response = initFaceVerify("cloudauth.cn-shanghai.aliyuncs.com", request);
|
|
|
+
|
|
|
+ InitFaceVerifyResponseBody.InitFaceVerifyResponseBodyResultObject resultObject = response.getBody().getResultObject();
|
|
|
+
|
|
|
+ System.out.println(response.getBody().getRequestId());
|
|
|
+ System.out.println(response.getBody().getCode());
|
|
|
+ System.out.println(response.getBody().getMessage());
|
|
|
+ System.out.println(response.getBody().getResultObject() == null ? null
|
|
|
+ : response.getBody().getResultObject().getCertifyId());
|
|
|
+ return resultObject;
|
|
|
+ }
|
|
|
+ private static InitFaceVerifyResponse initFaceVerifyAutoRoute(InitFaceVerifyRequest request) {
|
|
|
+ // 第一个为主区域Endpoint,第二个为备区域Endpoint。
|
|
|
+ List<String> endpoints = Arrays.asList("cloudauth.cn-shanghai.aliyuncs.com", "cloudauth.cn-beijing.aliyuncs.com");
|
|
|
+ InitFaceVerifyResponse lastResponse = null;
|
|
|
+ for (int i = 0; i < endpoints.size(); i++) {
|
|
|
+ try {
|
|
|
+ InitFaceVerifyResponse response = initFaceVerify(endpoints.get(i), request);
|
|
|
+ lastResponse = response;
|
|
|
+
|
|
|
+ // 服务端错误,切换到下个区域调用。
|
|
|
+ if (response != null) {
|
|
|
+ if (500 == response.getStatusCode()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (response.getBody() != null) {
|
|
|
+ if ("500".equals(response.getBody().getCode())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 正常返回
|
|
|
+ return lastResponse;
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ if (i == endpoints.size() - 1) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return lastResponse;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static InitFaceVerifyResponse initFaceVerify(String endpoint, InitFaceVerifyRequest request)
|
|
|
+ throws Exception {
|
|
|
+ // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
|
|
|
+ // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
|
|
|
+ // 本示例通过阿里云Credentials工具从环境变量中读取AccessKey,来实现API访问的身份验证。如何配置环境变量,请参见https://help.aliyun.com/document_detail/378657.html。
|
|
|
+ Config credentialConfig = new Config();
|
|
|
+ credentialConfig.setType("access_key");
|
|
|
+ //使用阿里云RAM用户的AK。最小的权限
|
|
|
+ credentialConfig.setAccessKeyId("LTAI5tCwkQRjuJYzbohaveEz");
|
|
|
+ credentialConfig.setAccessKeySecret("8VW0H8GL7hmm5td8cYxO49FcVLPzOj");
|
|
|
+ credentialConfig.setEndpoint(endpoint);
|
|
|
+ Client client = new Client(credentialConfig);
|
|
|
+ // 设置http代理。
|
|
|
+ //config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
|
|
|
+ // 设置https代理。
|
|
|
+ //config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
|
|
|
+
|
|
|
+
|
|
|
+ // 创建RuntimeObject实例并设置运行参数。
|
|
|
+ RuntimeOptions runtime = new RuntimeOptions();
|
|
|
+ runtime.readTimeout = 10000;
|
|
|
+ runtime.connectTimeout = 10000;
|
|
|
+
|
|
|
+ return client.initFaceVerifyWithOptions(request, runtime);
|
|
|
+ }
|
|
|
+}
|