文章目录

  • 前言
  • 一、购买API
  • 二、集成身份认证
  • 三、完成身份认证
  • 1、接口开发前期工作
  • 2、接口开发


前言

需求:我们输入真实姓名和身份证号就能验证,其技术在于阿里云的身份认证接口.

springcloud token登录验证源码 springcloud身份验证_API

一、购买API

阿里云相关身份认证API地址d=====( ̄▽ ̄*)b 顶

springcloud token登录验证源码 springcloud身份验证_springcloud_02


我们就先拿免费的试用一下吧

springcloud token登录验证源码 springcloud身份验证_spring boot_03


支付成功后,点击管理控制台

springcloud token登录验证源码 springcloud身份验证_springcloud_04


这三个参数待会要用到:AppKey、AppSecret、AppCode

我们回到一开始的购买界面,滑到下面会发现一个API接口的测试

springcloud token登录验证源码 springcloud身份验证_API_05


springcloud token登录验证源码 springcloud身份验证_java_06

二、集成身份认证

首先我们通过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,所以请求的参数较多,便封装成一个模型。这是前端请求的参数样例:

springcloud token登录验证源码 springcloud身份验证_spring boot_07


我分别封装成了: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;
}