文章目录
- 前言
- 一、购买API
- 二、集成身份认证
- 三、完成身份认证
- 1、接口开发前期工作
- 2、接口开发
前言
需求:我们输入真实姓名和身份证号就能验证,其技术在于阿里云的身份认证接口.
一、购买API
阿里云相关身份认证API地址:d=====( ̄▽ ̄*)b 顶
我们就先拿免费的试用一下吧
支付成功后,点击管理控制台
这三个参数待会要用到:AppKey、AppSecret、AppCode
我们回到一开始的购买界面,滑到下面会发现一个API接口的测试
二、集成身份认证
首先我们通过API接口的测试,需要建立一些模型,用于接收参数:
IdProperties、IdAutoConfiguration这两个类我是放在config包下面的
IdProperties.java:
@ConfigurationProperties(prefix = "identify")
@Data
public class IdProperties {
/**
* 对应你购买的appKey
*/
private String appKey;
/**
* 对应你购买的appSecret
*/
private String appSecret;
/**
* 对应你购买的appCode
*/
private String appCode;
/**
* 认证的url地址
* http://idcert.market.alicloudapi.com/idcard?idCard=%s&name=%s
*/
private String url;
}
IdAutoConfiguration.java:
@Configuration
@EnableConfigurationProperties(IdProperties.class)
public class IdAutoConfiguration {
private static IdProperties idProperties;
/**
* 发请求的工具
*/
private static RestTemplate restTemplate = new RestTemplate();
public IdAutoConfiguration(IdProperties idProperties) {
IdAutoConfiguration.idProperties = idProperties;
}
/**
* 用户信息的实名认证
* @param realName 用户的真实信息
* @param cardNum 用户的身份认证
* @return 验证结果
*/
public static boolean check(String realName, String cardNum) {
/**
* 本次请求我们是AppCode的形式验证:
* -H Authorization:APPCODE
*/
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", "APPCODE " + idProperties.getAppCode());
ResponseEntity<String> responseEntity = restTemplate.exchange(
// %s 是变量
String.format(idProperties.getUrl(), cardNum, realName),
HttpMethod.GET,
new HttpEntity<>(null, httpHeaders),
String.class
);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
String body = responseEntity.getBody();
JSONObject jsonObject = JSON.parseObject(body);
String status = jsonObject.getString("status");
// 验证成功
if ("01".equals(status)) {
return true;
}
}
return false;
}
}
三、完成身份认证
1、接口开发前期工作
因为前端请求的参数比较多,不单单阿里云身份认证的API,还携带了极验验证身份的API,所以请求的参数较多,便封装成一个模型。这是前端请求的参数样例:
我分别封装成了:UserAuthForm、GeetestForm:
GeetestForm.java:
@Data
@Slf4j
public class GeetestForm {
/**
* 极验的数据包
*/
private String geetest_challenge ;
private String geetest_seccode ;
private String geetest_validate ;
private String uuid ;
public void check(GeetestForm geetestForm, GeetestLib geetestLib, RedisTemplate<String, Object> redisTemplate){
String challenge = geetestForm.getGeetest_challenge();
String validate = geetestForm.getGeetest_validate();
String seccode = geetestForm.getGeetest_seccode();
int status = 0;
String userId = "";
// session必须取出值,若取不出值,直接当做异常退出
String statusStr = redisTemplate.opsForValue().get(GeetestLib.GEETEST_SERVER_STATUS_SESSION_KEY).toString();
status = Integer.valueOf(statusStr).intValue();
userId = redisTemplate.opsForValue().get(GeetestLib.GEETEST_SERVER_USER_KEY + ":" + geetestForm.getUuid()).toString();
GeetestLibResult result = null;
if (status == 1) {
/*
自定义参数,可选择添加
user_id 客户端用户的唯一标识,确定用户的唯一性;
作用于提供进阶数据分析服务,可在register和validate接口传入,不传入也不影响验证服务的使用;
若担心用户信息风险,可作预处理(如哈希处理)再提供到极验
client_type 客户端类型,web:电脑上的浏览器;
h5:手机上的浏览器,包括移动应用内完全内置的web_view;
native:通过原生sdk植入app应用的方式;
unknown:未知
ip_address 客户端请求sdk服务器的ip地址
*/
Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("user_id", userId);
paramMap.put("client_type", "web");
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
paramMap.put("ip_address", IpUtil.getIpAddr(servletRequestAttributes.getRequest()));
result = geetestLib.successValidate(challenge, validate, seccode, paramMap);
log.info("验证的结果为{}", JSON.toJSONString(result));
} else {
result = geetestLib.failValidate(challenge, validate, seccode);
}
if(result.getStatus()!=1){
log.error("验证异常",JSON.toJSONString(result,true));
throw new IllegalArgumentException("验证码验证异常");
}
}
}
UserAuthForm.java:
@Data
@ApiModel(value = "用户的身份认证信息")
public class UserAuthForm extends GeetestForm {
@NotBlank
@ApiModelProperty(value = "用户的真实名称")
private String realName;
@NotNull
@ApiModelProperty(value = "用户的证件类型")
private Integer idCardType;
@NotBlank
@ApiModelProperty(value = "用户的证件号码")
private String idCard;
}
然后就是配置application.yml(由于我的是拉取nacos的配置文件,所以我的是在nacos进行如下配置):
identify:
url: http://idcert.market.alicloudapi.com/idcard?idCard=%s&name=%s # 这个是在API测试获得的。而%s是变量
addKey: 填写自己的阿里云 AppKey
appSecret: 填写自己的阿里云 AppSecret
appCode: 填写自己的阿里云 AppCode
2、接口开发
下面就是开发接口及实现:
UserController.java:
@PostMapping("/authAccount")
@ApiOperation(value = "用户的实名认证")
@ApiImplicitParams({
@ApiImplicitParam(name = "userAuthForm", value = "真实姓名、身份证二要素")
})
public R identifyCheck(@RequestBody UserAuthForm userAuthForm) {
String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
boolean isOk = userService.identifyVerify(Long.valueOf(idStr), userAuthForm);
if (isOk) {
return R.ok();
}
return R.fail("认证失败");
}
UserService.java:
/**
* 用户的实名认证
* @param id 用户的id
* @param userAuthForm 认证的表单数据
* @return 认证的结果
*/
boolean identifyVerify(Long id, UserAuthForm userAuthForm);
UserServiceImpl.java:
/**
* 用户的实名认证
*
* @param id 用户的id
* @param userAuthForm 认证的表单数据
* @return 认证的结果
*/
@Override
public boolean identifyVerify(Long id, UserAuthForm userAuthForm) {
User user = getById(id);
Assert.notNull(user, "认证的用户不存在");
// 认证状态:0-未认证;1-初级实名认证;2-高级实名认证
Byte authStatus = user.getAuthStatus();
if (!authStatus.equals((byte)0)) {
throw new IllegalArgumentException("该用户已经认证成功了");
}
// 执行认证 效验
checkForm(userAuthForm);
// 实名认证
boolean check = IdAutoConfiguration.check(userAuthForm.getRealName(), userAuthForm.getIdCard());
if (!check) {
throw new IllegalArgumentException("该用户信息错误,请检查");
}
// 设置用户的认证属性
user.setAuthtime(new Date());
user.setAuthStatus((byte)1);
user.setRealName(userAuthForm.getRealName());
user.setIdCard(userAuthForm.getIdCard());
user.setIdCardType(userAuthForm.getIdCardType());
return updateById(user);
}
private void checkForm(UserAuthForm userAuthForm) {
userAuthForm.check(userAuthForm, geetestLib, redisTemplate);
}
以上便是整个开发流程,对于以上的接口便开发完成,为了方便大家参考,我便把项目中的User表放出来给大家参考(有亿点点长),最后倘若大家还有对这个API不明白的地方,可自行查看官网的请求示例进行测试ヽ(・ω・´メ)
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "`user`")
public class User {
/**
* 自增id
*/
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value="自增id")
private Long id;
/**
* 用户类型:1-普通用户;2-代理人
*/
@TableField(value = "`type`")
@ApiModelProperty(value="用户类型:1-普通用户;2-代理人")
private Byte type;
/**
* 用户名
*/
@TableField(value = "username")
@ApiModelProperty(value="用户名")
@NotBlank
private String username;
/**
* 国际电话区号
*/
@TableField(value = "country_code")
@ApiModelProperty(value="国际电话区号")
private String countryCode;
/**
* 手机号
*/
@TableField(value = "mobile")
@ApiModelProperty(value="手机号")
@NotBlank
private String mobile;
/**
* 密码
*/
@TableField(value = "`password`")
@ApiModelProperty(value="密码")
private String password;
/**
* 交易密码
*/
@TableField(value = "paypassword")
@ApiModelProperty(value="交易密码")
private String paypassword;
/**
* 交易密码设置状态
*/
@TableField(value = "paypass_setting")
@ApiModelProperty(value="交易密码设置状态")
private Boolean paypassSetting;
/**
* 邮箱
*/
@TableField(value = "email")
@ApiModelProperty(value="邮箱")
private String email;
/**
* 真实姓名
*/
@TableField(value = "real_name")
@ApiModelProperty(value="真实姓名")
private String realName;
/**
* 证件类型:1,身份证;2,军官证;3,护照;4,台湾居民通行证;5,港澳居民通行证;9,其他;
*/
@TableField(value = "id_card_type")
@ApiModelProperty(value="证件类型:1,身份证;2,军官证;3,护照;4,台湾居民通行证;5,港澳居民通行证;9,其他;")
private Integer idCardType;
/**
* 认证状态:0-未认证;1-初级实名认证;2-高级实名认证
*/
@TableField(value = "auth_status")
@ApiModelProperty(value="认证状态:0-未认证;1-初级实名认证;2-高级实名认证")
private Byte authStatus;
/**
* Google令牌秘钥
*/
@TableField(value = "ga_secret")
@ApiModelProperty(value="Google令牌秘钥")
private String gaSecret;
/**
* Google认证开启状态,0,未启用,1启用
*/
@TableField(value = "ga_status")
@ApiModelProperty(value="Google认证开启状态,0,未启用,1启用")
private Integer gaStatus;
/**
* 身份证号
*/
@TableField(value = "id_card")
@ApiModelProperty(value="身份证号")
private String idCard;
/**
* 代理商级别
*/
@TableField(value = "`level`")
@ApiModelProperty(value="代理商级别")
private Integer level;
/**
* 认证时间
*/
@TableField(value = "authtime")
@ApiModelProperty(value="认证时间")
private Date authtime;
/**
* 登录数
*/
@TableField(value = "logins")
@ApiModelProperty(value="登录数")
private Integer logins;
/**
* 状态:0,禁用;1,启用;
*/
@TableField(value = "`status`")
@ApiModelProperty(value="状态:0,禁用;1,启用;")
private Byte status;
/**
* 邀请码
*/
@TableField(value = "invite_code")
@ApiModelProperty(value="邀请码")
private String inviteCode;
/**
* 邀请关系
*/
@TableField(value = "invite_relation")
@ApiModelProperty(value="邀请关系")
private String inviteRelation;
/**
* 直接邀请人ID
*/
@TableField(value = "direct_inviteid")
@ApiModelProperty(value="直接邀请人ID")
private String directInviteid;
/**
* 0 否 1是 是否开启平台币抵扣手续费
*/
@TableField(value = "is_deductible")
@ApiModelProperty(value="0 否 1是 是否开启平台币抵扣手续费")
private Integer isDeductible;
/**
* 审核状态,1通过,2拒绝,0,待审核
*/
@TableField(value = "reviews_status")
@ApiModelProperty(value="审核状态,1通过,2拒绝,0,待审核")
private Integer reviewsStatus;
/**
* 代理商拒绝原因
*/
@TableField(value = "agent_note")
@ApiModelProperty(value="代理商拒绝原因")
private String agentNote;
/**
* API的KEY
*/
@TableField(value = "access_key_id")
@ApiModelProperty(value="API的KEY")
private String accessKeyId;
/**
* API的密钥
*/
@TableField(value = "access_key_secret")
@ApiModelProperty(value="API的密钥")
private String accessKeySecret;
/**
* 引用认证状态id
*/
@TableField(value = "refe_auth_id")
@ApiModelProperty(value="引用认证状态id")
private Long refeAuthId;
/**
* 修改时间
*/
@TableField(value = "last_update_time", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value="修改时间")
private Date lastUpdateTime;
/**
* 创建时间
*/
@TableField(value = "created", fill = FieldFill.INSERT)
@ApiModelProperty(value="创建时间")
private Date created;
}