6.0 KiB
实名认证接口(身份证二要素核验)
服务商:阿里云市场 - 天眼数聚「身份证实名核验优质版」。 传入姓名、身份证号,校验二要素是否一致,同时返回生日、性别、籍贯等信息。
旧接口
https://sinocheck2.market.alicloudapi.com/fortest/ttttt已下线,参数名为id_number、 响应为顶层status/result的那一版不再使用,全部改走下面的新接口。
接口信息
| 项 | 值 |
|---|---|
| 调用地址 | https://eid.shumaidata.com/eid/check |
| 请求方式 | POST |
| 返回类型 | JSON |
| 鉴权方式 | 请求头 Authorization: APPCODE <AppCode>(阿里云市场简单身份认证) |
请求参数(Query)
| 字段名称 | 类型 | 必填 | 字段详情 |
|---|---|---|---|
| name | string | Y | 姓名 |
| idcard | string | Y | 身份证号 |
Body 无参数。
成功响应
解析结果时,先判断 code:code=0 时再判断 result.res;code!=0 表示调用已失败,无需再继续。
{
"code": "0",
"message": "成功",
"result": {
"name": "冯**",
"idcard": "350*********9422",
"res": "1",
"description": "一致",
"sex": "男",
"birthday": "19*****0",
"address": "江西省****区"
}
}
result.res 核验结果状态码:
| res | 含义 |
|---|---|
| 1 | 一致 |
| 2 | 不一致 |
| 3 | 无记录(预留) |
res=3(库无)的常见原因:
- 现役军人、武警官兵、特殊部门人员及特殊级别官员;
- 退役不到 2 年的军人和士兵(根据军衔、兵种不同,一般为 2 年);
- 户口迁出,且没有在新的迁入地迁入;
- 户口迁入新迁入地,当地公安系统未将迁移信息上报到公安部;
- 更改姓名,当地公安系统未将更改信息上报到公安部;
- 移民;
- 未更换二代身份证;
- 死亡;
- 身份证号确实不存在。
失败响应
{
"code": "20310",
"message": "请求姓名不标准:姓名为空或者包含特殊字符",
"result": {}
}
注意 code 是业务返回码,并非 HTTP 状态码。实测业务失败时 HTTP 状态码会跟着变(例如身份证号错误时
返回 400 且 "result": null),因此解析必须以 code 为准,不能按 HTTP 状态码判断失败类型。
网关层错误(AppCode 无效、限流、额度耗尽)不会返回上面的 JSON,响应体为空,原因只在响应头:
x-ca-error-code: A401AC
x-ca-error-message: Invalid AppCode `not exists`
常见网关错误码:A401AC(AppCode 无效,HTTP 401)、B403MQ(套餐额度耗尽,HTTP 403)、
B403FQ(调用频率过高,HTTP 403)。额度耗尽与限流都是 403,但额度耗尽靠重试不会恢复,必须续购。
错误码
| 错误码 | 错误信息 | 描述 |
|---|---|---|
| 0 | 成功 | 成功 |
| 400 | 参数错误 | 参数错误 |
| 20010 | 身份证号为空或非法 | 身份证号为空或非法 |
| 20310 | 姓名为空或非法 | 姓名为空或非法 |
| 404 | 请求资源不存在 | 请求资源不存在 |
| 500 | 系统内部错误,请联系服务商 | 系统内部错误,请联系服务商 |
| 501 | 第三方服务异常 | 第三方服务异常 |
| 604 | 接口停用 | 接口停用 |
| 1001 | 其他,以实际返回为准 | 其他,以实际返回为准 |
本项目的接入
实现位于 backend/internal/modules/realname/cloudmarket_provider.go,配置项:
REALNAME_PROVIDER=cloudmarket
REALNAME_CLOUDMARKET_URL=https://eid.shumaidata.com/eid/check
REALNAME_CLOUDMARKET_APPCODE=<阿里云市场 AppCode>
响应与内部状态、错误的映射关系:
| 服务商返回 | 内部结果 |
|---|---|
code=0 且 res=1 |
认证通过(verified),记录通过时间 |
code=0 且 res=2 或 3 |
认证驳回(rejected),失败原因取 description |
code 为 400 / 20010 / 20310 |
ErrInvalidRealnameInput,接口返回 400 |
code 为 404 / 604 |
ErrProviderConfigInvalid,接口返回 503 |
code 为 500 / 501 / 1001 等其他值 |
ErrProviderUnavailable,接口返回 502 |
403 且 x-ca-error-code=B403MQ(额度耗尽) |
ErrProviderQuotaExhausted,接口返回 503「额度已用尽」 |
| 其他 403 / 429(网关限流) | ErrProviderRateLimited,接口返回 429 |
| HTTP 401 / 404 且无业务 code(AppCode 或路径错误) | ErrProviderConfigInvalid,接口返回 503 |
业务 code 的优先级高于 HTTP 状态码,只有响应体里拿不到 code 时才按状态码与网关错误头判断。
更换 AppCode
AppCode 与阿里云市场的订购关系绑定,换商品必须换 AppCode:旧商品的 AppCode 调用本接口会得到
401 Invalid AppCode 'not exists'。在「阿里云市场 → 已购买的服务 → 对应商品」获取 AppCode 后,
只需更新服务器 backend/.env 的 REALNAME_CLOUDMARKET_APPCODE 并重启后端,无需重新发版。
该接口不返回服务商流水号,因此 user_realname.provider_order_no 对 cloudmarket 渠道为空。
姓名与身份证号由本项目自行脱敏入库,并用 pkg/crypto 加密保存完整值。
身份证唯一性
同一身份证号最多绑定一个已实名账号:
user_realname.id_no_hash保存身份证号的 HMAC-SHA256 盲索引,uk_user_realname_id_no_hash唯一索引兜底并发请求。- 指纹密钥优先使用
REALNAME_ID_HASH_KEY,未配置时回退到FIELD_ENCRYPTION_KEY。更换密钥不会丢失唯一性:旧指纹查不到时会退回解密候选比对,并在命中时补写新指纹。 - 已实名用户再次调用实名校验会返回
realname_already_verified。 - 同一身份证绑定第二个账号会返回
realname_id_no_used;后台人工实名同样执行该校验。 - 存量记录没有指纹或指纹使用旧密钥时,按
masked_id_no取出候选并解密做精确比对,命中后自动补写当前指纹,兼容历史上已加密保存的实名数据。