Commit b8f29573 authored by gaoyingwei's avatar gaoyingwei

添加 实名认证

parent af67b5c7
......@@ -176,3 +176,10 @@ wx:
# 微信支付的商户密钥
key: b90d421495604c33a943bb9be12d28c0
certPath: /working/file/config/certs/apiclient_cert.p12
faceverfiy:
ali:
sceneId: 1000012328
accessKeyId: LTAI5tFCR21anCpo27GWp75V
accessKeySecret: W1YlOyKsYGGQ8Cs9SSgjb68COuUh2d
endpoints: ["cloudauth.cn-shanghai.aliyuncs.com", "cloudauth.cn-beijing.aliyuncs.com"]
......@@ -122,6 +122,7 @@ cy:
- "/office/callback"
- "/app/open/**"
- "/app/wxMiniApp/**"
- "/faceVerify/callbackFaceVerify"
permitStatic: [ "/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.js", "/**/*.css","/swagger-ui/*" ]
logoutSuccessUrl: "/login"
loginPage: "/login"
......
# 1. redis
cy_redis:
ip: 127.0.0.1
port: 6379
ip: 106.3.97.198
port: 20161
password:
database: 7
database: 0
# 2. rabbitMq
cy_rabbitMq:
......@@ -40,11 +40,11 @@ cy_minio:
readSecretKey: xxxxxxxxxxxxxx
cy_db:
ip: 106.3.99.36
port: 20096
username: zt
password: zt
db: zt_db
ip: 106.3.97.198
port: 20160
username: root
password: root
db: cust
cy:
model:
swagger3Config: true
......@@ -165,3 +165,10 @@ wx:
# 微信支付的商户密钥
key: b90d421495604c33a943bb9be12d28c0
certPath: /working/file/config/certs/apiclient_cert.p12
faceverfiy:
ali:
sceneId: 1000012328
accessKeyId: LTAI5tFCR21anCpo27GWp75V
accessKeySecret: W1YlOyKsYGGQ8Cs9SSgjb68COuUh2d
endpoints: ["cloudauth.cn-shanghai.aliyuncs.com", "cloudauth.cn-beijing.aliyuncs.com"]
......@@ -169,10 +169,16 @@
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
<!-- 阿里实人认证 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>cloudauth20190307</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<finalName>asset_api</finalName>
<finalName>cust_api</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
......
package org.rcisoft.business.faceVerify.bean;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "faceverfiy.ali")
public class FaceVerifyAliComp {
/**
* 场景id
*/
public Long sceneId;
//访问密钥 ID
public String accessKeyId;
//访问密钥
public String accessKeySecret;
//区域
public String[] endpoints;
}
package org.rcisoft.business.faceVerify.controller;
/*固定导入*/
import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import org.rcisoft.business.faceVerify.service.FaceVerifyService;
import org.rcisoft.business.memInfo.entity.MemInfo;
import org.rcisoft.core.anno.CyOpeLogAnno;
import org.rcisoft.core.constant.CyMessCons;
import org.rcisoft.core.controller.CyPaginationController;
import org.rcisoft.core.model.CyPersistModel;
import org.rcisoft.core.operlog.enums.CyLogTypeEnum;
import org.rcisoft.core.result.CyResult;
import org.rcisoft.core.util.CyResultGenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* Created by cy on 2024年12月20日 下午3:35:34.
*/
@RestController
@RequestMapping("/faceVerify")
public class FaceVerifyController extends CyPaginationController<MemInfo> {
@Autowired
private FaceVerifyService faceVerifyService;
@CyOpeLogAnno(title = "system-发起认证请求", businessType = CyLogTypeEnum.OTHER)
@Operation(summary="发起认证请求", description="发起认证请求")
@PostMapping(value = "/initFaceVerify")
public CyResult initFaceVerify(@RequestBody InitFaceVerifyRequest dto, HttpServletRequest request) {
Map<String,String> data = faceVerifyService.initFaceVerify(request,dto);
return CyResultGenUtil.builder(new CyPersistModel(1),
CyMessCons.MESSAGE_ALERT_SUCCESS,
CyMessCons.MESSAGE_ALERT_ERROR,
data);
}
@CyOpeLogAnno(title = "system-获取认证详细数据", businessType = CyLogTypeEnum.OTHER)
@Operation(summary="获取认证详细数据", description="获取认证详细数据")
@PostMapping(value = "/describeFaceVerify")
public CyResult describeFaceVerify(@RequestParam String certifyId) {
String data = faceVerifyService.describeFaceVerify(null,certifyId);
return CyResultGenUtil.builder(new CyPersistModel(1),
CyMessCons.MESSAGE_ALERT_SUCCESS,
CyMessCons.MESSAGE_ALERT_ERROR,
data);
}
// @CyOpeLogAnno(title = "system-获取认证详细数据", businessType = CyLogTypeEnum.OTHER)
@Operation(summary="实人认证回调地址", description="实人认证回调地址")
@PostMapping(value = "/callbackFaceVerify")
public void callbackFaceVerify(@RequestParam String callbackToken,@RequestParam String certifyId,@RequestParam String passed) {
faceVerifyService.callbackFaceVerify(callbackToken,certifyId,passed);
}
}
package org.rcisoft.business.faceVerify.service;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.rcisoft.business.memInfo.entity.MemInfo;
import org.rcisoft.core.model.CyPersistModel;
import java.util.Map;
public interface FaceVerifyService {
/**
* 发起认证请求
* @param memInfo
* @return
*/
Map<String,String> initFaceVerify(HttpServletRequest request,InitFaceVerifyRequest dto);
/**
* 获取认证详细数据
* @param certifyId
* @return
*/
String describeFaceVerify(String userId,String certifyId);
/**
* 获取认证详细数据回调地址
* @param certifyId
* @return
*/
void callbackFaceVerify(String callbackToken, String certifyId, String passed);
}
package org.rcisoft.business.faceVerify.service.impl;
import com.aliyun.cloudauth20190307.Client;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.DescribeFaceVerifyResponse;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyRequest;
import com.aliyun.cloudauth20190307.models.InitFaceVerifyResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.rcisoft.business.faceVerify.bean.FaceVerifyAliComp;
import org.rcisoft.business.faceVerify.service.FaceVerifyService;
import org.rcisoft.business.memInfo.dao.MemInfoRepository;
import org.rcisoft.business.memInfo.entity.MemInfo;
import org.rcisoft.business.memInfo.service.MemInfoService;
import org.rcisoft.core.exception.CyServiceException;
import org.rcisoft.core.jwt.util.CyJwtUtil;
import org.rcisoft.core.model.CyPersistModel;
import org.rcisoft.core.util.CyAESUtils;
import org.rcisoft.core.util.CyUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Service
@Transactional(readOnly = true,propagation = Propagation.NOT_SUPPORTED)
@Slf4j
public class FaceVerifyServiceImpl extends ServiceImpl<MemInfoRepository, MemInfo> implements FaceVerifyService {
@Autowired
private FaceVerifyAliComp faceVerifyAliComp;
@Autowired
private MemInfoRepository memInfoRepository;
@Autowired
private CyJwtUtil cyJwtUtil;
/**
* 发起认证请求
* @param MetaInfo
* @return
*/
@Override
public Map<String,String> initFaceVerify(HttpServletRequest httpServletRequest,InitFaceVerifyRequest dto) {
MemInfo memInfo = memInfoRepository.getInfoByUserId(CyUserUtil.getAuthenBusinessId());
String idCard = CyAESUtils.decrypt(memInfo.getMemIdcard());
String name = CyAESUtils.decrypt(memInfo.getMemRealName());
Map<String,String> map = new HashMap<>();
InitFaceVerifyRequest request = new InitFaceVerifyRequest();
// 场景ID+L。
request.setSceneId(faceVerifyAliComp.getSceneId());
// 设置商户请求的唯一标识。(请自己生成一个不超过32位数的数字及字母字符串)
LocalDateTime now = LocalDateTime.now();
String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String uuid = UUID.randomUUID().toString().replace("-", "");
String outerOrderNo = timestamp + uuid.substring(0, 14);
request.setOuterOrderNo(outerOrderNo);
// 认证方案。
request.setProductCode("ID_PRO");
// 模式。LIVENESS(默认):眨眼动作活体检测。
request.setModel("LIVENESS");
// 不同证件类型,取值均为IDENTITY_CARD。
request.setCertType("IDENTITY_CARD");
// 您的终端用户的真实姓名。
request.setCertName(name);
// 您的终端用户的证件号码。
request.setCertNo(idCard);
// MetaInfo环境参数,此参数应由前端js获取并传入。
request.setMetaInfo(dto.getMetaInfo());
// 认证结束后回跳页面的链接地址。。
request.setReturnUrl("https://www.aliyundoc.com");
request.setCallbackUrl("https://xxxxxx/faceVerify/callbackFaceVerify");
request.setCallbackToken(cyJwtUtil.getToken(httpServletRequest));
InitFaceVerifyResponse response = initFaceVerifyAutoRoute(request);
log.info("requestId:"+response.getBody().getCode());
log.info("certifyId:"+response.getBody().getResultObject().getCertifyId());
if ("200".equals(response.getBody().getCode())){
map.put("requestId",response.getBody().getRequestId());
map.put("certifyId",response.getBody().getResultObject().getCertifyId());
map.put("certifyUrl",response.getBody().getResultObject().getCertifyUrl());
} else {
log.error("发起认证请求失败:"+response.getBody().getMessage());
throw new CyServiceException("发起认证请求失败");
}
return map;
}
private InitFaceVerifyResponse initFaceVerifyAutoRoute(InitFaceVerifyRequest request) {
// 第一个为主区域Endpoint,第二个为备区域Endpoint。
List<String> endpoints = List.of(faceVerifyAliComp.endpoints);
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 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。
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
Config config = new Config();
config.setCredential(credentialClient);
config.setEndpoint(endpoint);
// 设置http代理。
//config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
// 设置https代理。
//config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
Client client = new Client(config);
// 创建RuntimeObject实例并设置运行参数。
RuntimeOptions runtime = new RuntimeOptions();
runtime.readTimeout = 10000;
runtime.connectTimeout = 10000;
return client.initFaceVerifyWithOptions(request, runtime);
}
/**
* 获取认证详细数据
* @param certifyId
* @return
*/
@Override
public String describeFaceVerify(String userId,String certifyId) {
if (userId == null)
userId = CyUserUtil.getAuthenBusinessId();
// Map<String, String> map = new HashMap<>();
MemInfo memInfo = memInfoRepository.getInfoByUserId(userId);
if ("0".equals(memInfo.getMemRealAuthen())) {
// 创建API请求并设置参数。
DescribeFaceVerifyRequest request = new DescribeFaceVerifyRequest();
// 场景ID+L。
request.setSceneId(faceVerifyAliComp.getSceneId());
// CertifyId在InitFaceVerify接口的返回值中。
request.setCertifyId(certifyId);
DescribeFaceVerifyResponse response = describeFaceVerifyAutoRoute(request);
log.info(response.getBody().getRequestId());
log.info(response.getBody().getCode());
log.info(response.getBody().getMessage());
log.info("passed:" + response.getBody().getResultObject().getPassed());
log.info(response.getBody().getResultObject().getSubCode());
if ("200".equals(response.getBody().getCode())) {
// map.put("requestId", response.getBody().getRequestId());
// map.put("passed", response.getBody().getResultObject().getPassed());
// map.put("subCode", response.getBody().getResultObject().getSubCode());
if ("T".equals(response.getBody().getResultObject().getPassed())) {
memInfo.setMemRealAuthen("1");
memInfo.setMemRealAuthenDate(new Date());
memInfoRepository.updateById(memInfo);
}
} else {
log.error("获取认证详细数据失败:" + response.getBody().getMessage());
throw new CyServiceException("获取认证详细数据失败");
}
}
return memInfo.getMemRealAuthen();
}
private DescribeFaceVerifyResponse describeFaceVerifyAutoRoute(DescribeFaceVerifyRequest request) {
// 第一个为主区域Endpoint,第二个为备区域Endpoint。
List<String> endpoints = List.of(faceVerifyAliComp.endpoints);
DescribeFaceVerifyResponse lastResponse = null;
for (int i = 0; i < endpoints.size(); i++) {
try {
DescribeFaceVerifyResponse response = describeFaceVerify(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) {
if (i == endpoints.size() - 1) {
throw new RuntimeException(e);
}
}
}
return lastResponse;
}
private DescribeFaceVerifyResponse describeFaceVerify(String endpoint, DescribeFaceVerifyRequest request)
throws Exception {
// 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
// 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
//本示例通过阿里云Credentials工具从环境变量中读取AccessKey,来实现API访问的身份验证。如何配置环境变量,请参见https://help.aliyun.com/document_detail/378657.html。
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
Config config = new Config();
config.setCredential(credentialClient);
config.setEndpoint(endpoint);
Client client = new Client(config);
RuntimeOptions runtime = new RuntimeOptions();
runtime.readTimeout = 10000;
runtime.connectTimeout = 10000;
return client.describeFaceVerifyWithOptions(request, runtime);
}
@Override
public void callbackFaceVerify(String callbackToken, String certifyId, String passed) {
String userId = CyUserUtil.getUserInfoStrProp(callbackToken,CyUserUtil.USER_ID);
if (userId!=null){
log.info("回调certifyId:"+certifyId);
log.info("回调passed:"+passed);
MemInfo memInfo = memInfoRepository.getInfoByUserId(userId);
//认证成功
if ("0".equals(memInfo.getMemRealAuthen()) && "200".equals(passed)) {
memInfo.setMemRealAuthen("1");
memInfo.setMemRealAuthenDate(new Date());
memInfoRepository.updateById(memInfo);
}
}
}
}
......@@ -85,5 +85,12 @@ public interface MemInfoRepository extends CyBaseMapper<MemInfo> {
List<opmArticleDTO> getArticleCountByDateRangeNo(@Param("startDate") LocalDate startDate,@Param("endDate") LocalDate endDate);
List<opmArticleDTO> getArticleCountByMonthRangeNo(@Param("startDateMonth")LocalDate startDateMonth,@Param("endDate") LocalDate endDate);
/**
* 查询加密字段
* @param businessId
* @return
*/
MemInfo getInfoByUserId(String userId);
}
......@@ -489,4 +489,9 @@
GROUP BY DATE_FORMAT(a.create_date, '%Y-%m')
</select>
<select id="getInfoByUserId" resultType="org.rcisoft.business.memInfo.entity.MemInfo">
select * from mem_info where user_id = #{userId} and del_flag = 0
</select>
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment