1.业务介绍
实名认证,说白了就是验证客户端用户的这个人真实性,可采用的第三方服务有高级点的如人脸骨骼识别,声音识别,瞳孔识别等等。我们采用简单的身份证、姓名、手机号3要素识别方式。
2.实现及代码
1.这类身份证和姓名的公共数据,我们采用聚合平台提供的公共数据服务接口,也可以接入其他公共数据服务平台。
2.登录聚合平台,进行注册和接口选用。
3.这块身份证姓名合法性验证接口服务的价格可不便宜(失败或成功都算一次,一次5毛),代码中要注意对已经认证的人进行处理,还需要防止乱刷接口。
3.代码实现
/**
* 获取短信验证码
*
* @param phone 手机号
* @return 返回
*/
@Override
public Object getCode(String phone) {
// 获取请求IP
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equals(ip)) {
ip = "" + request.getHeader("Proxy-Client-IP");
}
if (ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equals(ip)) {
ip = "" + request.getHeader("WL-Proxy-Client-IP");
}
if (ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equals(ip)) {
ip = "" + request.getRemoteAddr();
}
Object attribute = session.getAttribute(ip);
if (attribute == null) {
session.setMaxInactiveInterval(5 * 60);
session.setAttribute(ip, 1);
} else {
switch (attribute.toString()) {
case "1":
session.setAttribute(ip, 2);
break;
case "2":
session.setAttribute(ip, 3);
break;
case "3":
return false;
}
}
int random = (int) ((Math.random() * 9 + 1) * 100000);
String code = String.valueOf(random);
String valCode = "#code#=" + random;
try {
CodeUtil.print(phone, valCode);
} catch (Exception e) {
log.error(e.getMessage());
}
CacheUtil.put(phone, code);
return true;
}
/**
* 打印请求结果
*
* @param mobile 手机号
* @param variable 模板变量
*/
public static void print(String mobile, String variable) throws Exception {
//发送http请求的url
String url = String.format(URL, mobile, TPL_ID, URLEncoder.encode(variable, "utf-8"), KEY);
String response = doGet(url);
JSONObject jsonObject = JSONObject.parseObject(response);
int error_code = jsonObject.getInteger("error_code");
if (error_code == 0) {
JSONObject result = jsonObject.getJSONObject("result");
log.info("短信验证码请求结果,result:{}", result.toJSONString());
} else {
log.error("短信验证码请求结果,调用接口失败,失败原因reason:{}", jsonObject.getString("reason"));
throw new NullPointerException();
}
}
/**
* 实名认证
*
* @param name 姓名
* @param idCard 身份证号
* @param userPhone 手机号
* @param code 手机验证码
* @return 返回
*/
@Override
public boolean certification(String name, String idCard, String userPhone, String code) {
Object code_cache = CacheUtil.get(userPhone);
Long userId = TokenUtil.getTokenUserId();
if (code == null) {
log.error("实名认证:验证码为空!");
return false;
}
if (code_cache != null) {
if (!code.equals(code_cache.toString())) {
log.error("实名认证:验证码不对!");
return false;
}
} else {
log.error("实名认证:验证码无缓存!");
return false;
}
User user = this.getById(userId);
user.setUserPhone(userPhone);
if (user.getUserIdcard() != null) {
log.error("实名认证:用户身份证号已存在!");
return false;
}
boolean valid = IdcardUtil.isValidCard(idCard);
if (name != null && valid) {
boolean result = IdCardUtil.toCall(idCard, name);
if (result) {
user.setUserName(name);
user.setUserIdcard(idCard);
this.updateById(user);
return true;
}
}
log.error("实名认证:用户实名认证失败!");
return false;
}
/**
* 调聚合数据接口
*
* @param idCard 身份证号
* @param realname 真是姓名
*/
public static boolean toCall(String idCard, String realname) {
//发送http请求的url
String url = String.format(URL, KEY, idCard, realname);
String response = doGet(url);
System.out.println(response);
JSONObject jsonObject = JSONObject.parseObject(response);
int error_code = jsonObject.getInteger("error_code");
if (error_code == 0) {
int res = jsonObject.getJSONObject("result").getInteger("res");
return res == 1;
} else {
return false;
}
}