package com.nova.sankuai.infra.utils.chuxin;
|
|
import com.alibaba.fastjson.JSON;
|
import com.nova.sankuai.domain.dto.chuxin.ChuxinData;
|
import com.nova.sankuai.domain.dto.chuxin.ChuxinResult;
|
import com.nova.sankuai.infra.config.CommonException;
|
import com.nova.sankuai.infra.utils.ResultJson;
|
import com.nova.sankuai.security.HttpClientUtil;
|
import lombok.RequiredArgsConstructor;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.stereotype.Component;
|
|
import java.io.UnsupportedEncodingException;
|
import java.security.MessageDigest;
|
import java.security.NoSuchAlgorithmException;
|
import java.util.*;
|
|
/**
|
* 储信数据·身份认证
|
*/
|
@Component
|
@RequiredArgsConstructor
|
@Slf4j
|
public class ChuxinDataUtil {
|
/**
|
* 登录管理平台应用管理可查看获取appId和appSecret
|
*/
|
private final static String appId = "1754b210";
|
private final static String tokenId = "82808081914b210201914b2102930000";
|
|
public ResultJson getRemoteResult(String idcard, String name) {
|
// 接口地址,具体接口参见接口文档,每个接口有不同的url地址
|
String url = "https://kyc.chuxindata.com/identity/verifyIdcard";
|
|
Map<String, String> param = new HashMap<String, String>();
|
|
// 所需入参,请参照具体接口文档调整入参, 请注意区分大小写
|
param.put("name", name);
|
param.put("idcard", idcard);
|
|
|
// 生成TokenKey
|
// 注意:进行MD5摘要时,不能传入appId参数
|
String tokenKey = getTokenKey(url, tokenId, param);
|
param.put("tokenKey", tokenKey);
|
|
// 注意:appId参数需要在请求的时候作为入参传入,appId不参与MD5摘要
|
param.put("appId", appId);
|
|
// http的post请求
|
String result = HttpClientUtil.doPostChuxin(url, param);
|
if (StringUtils.isBlank(result)) {
|
log.error("储信数据·身份证二要素认证发生错误,icCard:{} name:{},发生错误,返回参数为:{}", idcard, name, result);
|
throw new CommonException("服务器发生异常!");
|
}
|
ChuxinData chuxinData = JSON.parseObject(result, ChuxinData.class);
|
if (Objects.isNull(chuxinData)) {
|
log.error("储信数据·身份证二要素认证发生错误,icCard:{} name:{},发生错误,返回参数为:{}", idcard, name, result);
|
throw new CommonException("服务器发生异常!");
|
}
|
if (chuxinData.getStatus().intValue() != 0) {
|
log.info("储信数据·身份证二要素认证失败,icCard:{} name:{},返回参数为:{}", idcard, name, result);
|
throw new CommonException("身份证和姓名不匹配!");
|
}
|
ChuxinResult cr = chuxinData.getData();
|
if (Objects.isNull(cr)) {
|
log.error("储信数据·身份证二要素认证发生错误,icCard:{} name:{},返回参数为:{}", idcard, name, result);
|
throw new CommonException("服务器发生异常!");
|
}
|
|
if (!"1".equals(cr.getResult())) {
|
log.info("储信数据·身份证二要素认证失败,icCard:{} name:{},返回参数为:{}", idcard, name, result);
|
throw new CommonException("身份证和姓名不匹配!");
|
}
|
log.info("储信数据·身份证二要素认证成功,icCard:{} name:{},返回参数为:{}", idcard, name, result);
|
return ResultJson.ok("ok");
|
}
|
|
/**
|
* 生成TokenKey
|
*
|
* @param url
|
* @param tokenId
|
* @param param
|
* @return
|
*/
|
public String getTokenKey(String url, String tokenId, Map<String, String> param) {
|
String paramStr = sortParam(param);
|
return md5Hex(url + tokenId + paramStr);
|
}
|
|
/**
|
* 生成参数字符串,参数key按字典序排列
|
*
|
* @param param
|
* @return
|
*/
|
public String sortParam(Map<String, String> param) {
|
if (null == param || 0 == param.size()) {
|
return "";
|
}
|
// 排序键,按照字母先后进行排序
|
Iterator<String> iterator = param.keySet().iterator();
|
String[] arr = new String[param.size()];
|
for (int i = 0; iterator.hasNext(); i++) {
|
arr[i] = iterator.next();
|
}
|
Arrays.sort(arr);
|
// 生成进行MD5摘要的字符串
|
StringBuffer sb = new StringBuffer();
|
for (String key : arr) {
|
String value = param.get(key);
|
if (StringUtils.isNotBlank(value)) {
|
sb.append(key).append("=").append(value).append(",");
|
}
|
}
|
// 检查结果
|
if (sb.length() > 0) {
|
return sb.substring(0, sb.length() - 1);
|
} else {
|
return "";
|
}
|
}
|
|
/**
|
* 对字符串进行md5摘要,然后转化成16进制字符串
|
* 使用标准的md5摘要算法
|
*
|
* @param text
|
* @return
|
*/
|
public String md5Hex(String text) {
|
try {
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
byte[] bytes = md5.digest(text.trim().getBytes("UTF-8"));
|
StringBuilder sb = new StringBuilder();
|
for (int i = 0; i < bytes.length; i++) {
|
int high = (bytes[i] >> 4) & 0x0f;
|
int low = bytes[i] & 0x0f;
|
sb.append(high > 9 ? (char) ((high - 10) + 'a') : (char) (high + '0'));
|
sb.append(low > 9 ? (char) ((low - 10) + 'a') : (char) (low + '0'));
|
}
|
return sb.toString();
|
} catch (NoSuchAlgorithmException e) {
|
log.error("储信数据·身份班证二要素认证:{},系统不支持MD5算法:", text, e);
|
e.printStackTrace();
|
} catch (UnsupportedEncodingException e) {
|
log.error("储信数据·身份班证二要素认证:{},系统不支持指定的编码格式:", text, e);
|
}
|
return null;
|
}
|
}
|