/identity/liveness_idnumber_verification
1.接口描述
该接口在身份核验的基础上,结合用户的活体检测动作,基于模型算法的能力,优先进行图片质量检测,判断用户图片是否清晰,是否过度曝光等;再对照片进行人像定位,特征提取,并进行防hack验证;并最终判断是否为用户本人。
注1:此接口只提供比对相似度分数,不提供比对照片;
注2:此接口只能配合Android活体检测SDK或者iOS活体检测SDK使用;
注3:protobuf文件中包含加密的人脸图片、视频等活体数据,与移动端SDK设置参数OUTPUT_TYPE有关;
注4:文档中描述的“protobuf文件”、“加密文件”、“二进制文件”均为同一个意思。
请求方式
POST
请求 URL
https://cloudapi.linkface.cn/identity/liveness_idnumber_verification
2.请求参数
字段 | 类型 | 必需 | 描述 |
---|---|---|---|
api_id | string | 是 | API 账户 |
api_secret | string | 是 | API 密钥 |
name | string | 是 | 姓名 |
id_number | string | 是 | 身份证号码 |
liveness_data_file | file | 见下方注释 | 活体检测SDK返回的protobuf文件。上传本地文件时选取此参数 |
liveness_data_url | string | 见下方注释 | 活体检测SDK返回的protobuf文件的url。采用抓取网络文件方式时选取此参数 |
liveness_data_id | string | 见下方注释 | 活体检测SDK返回的protobuf文件的id。在云端上传过文件可选取此参数 |
请求参数
liveness_data_file
,liveness_data_url
与liveness_data_id
三选一。
3.返回参数
字段 | 类型 | 描述 |
---|---|---|
request_id | string | 本次请求的id |
status | string | 返回状态,正常为 OK ,其他值表示失败。详见错误码 |
hack_score | float | 防hack得分,取值范围是0~1。值越大表示被hack的可能性越大 |
verify_score | float | 置信度。取值范围为 0~1,值越大表示两张照片是同一个人的可能性越大 |
liveness_data_id | string | 云端protobuf文件的id。如果使用file、url方式上传protobuf文件返回此参数 |
当图片中存在多个人脸时,系统会选出其中最大的人脸进行比对。
置信度阈值与错误率对应关系:
阈值 | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 | 0.9 |
---|---|---|---|---|---|---|
错误率 | 十分之一 | 百分之一 | 千分之一 | 万分之一 | 十万分之一 | 百万分之一 |
> 备注:verify_score阈值为0.7,由行业大数据训练得到,大于等于0.7是同一人
输出示例:
{
"request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e",
"status": "OK",
"hack_score": "xxx",
"verify_score": "xxxxx",
"liveness_data_id": "xxxxx"
}
4.错误码
状态码 | status 字段 |
说明 |
---|---|---|
400 |
PHOTO_SERVICE_ERROR | 数据源服务出错,详情见字段 reason |
400 |
ENCODING_ERROR | 参数非UTF-8编码 |
400 |
DOWNLOAD_TIMEOUT | 网络地址获取超时,详情见字段 image |
400 |
DOWNLOAD_ERROR | 网络地址获取失败,详情见字段 image |
400 |
WRONG_LIVENESS_DATA | liveness_data 出错 |
400 |
NO_FACE_DETECTED | 图片未检测出人脸 ,详情见字段 image |
400 |
INVALID_ARGUMENT | 请求参数错误,具体原因见 reason 字段内容 |
401 |
UNAUTHORIZED | 账号或密钥错误 |
401 |
KEY_EXPIRED | 账号过期,具体情况见 reason 字段内容 |
403 |
RATE_LIMIT_EXCEEDED | 调用频率超出限额 |
403 |
NO_PERMISSION | 无调用权限 |
403 |
OUT_OF_QUOTA | 调用次数超出限额 |
404 |
NOT_FOUND | 请求路径错误 |
500 |
INTERNAL_ERROR | 服务器内部错误 |
错误情况主要分为四种情况
1.账号和服务器报错,错误码为401、403、404、500
输出报错样例:
{
"status": "RATE_LIMIT_EXCEEDED",
"request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e"
}
2.输入参数报错,错误码为400,status
为ENCODING_ERROR、DOWNLOAD_TIMEOUT、DOWNLOAD_ERROR、INVALID_ARGUMENT,其中根据status
字段不同输出image
(指哪一张图片出错)或reason
输出报错样例:
{
"status": "ENCODING_ERROR",
"image": "liveness"
"request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e"
}
注:我们会对输入用户姓名和身份证进行预判,如果输入错误,status
为INVALID_ARGUMENT,reason
字段的描述为:Invalid name 或Invalid idcard number
3.错误码为400,status
为PHOTO_SERVICE_ERROR错误时,reason
字段的描述和收费情况如下:
reason 字段 |
描述 | 是否收费 |
---|---|---|
Gongan photo doesn’t exist | 姓名和身份证号匹配,近照不存在 | 是 |
Name and idcard number doesn’t match | 姓名与身份证号不匹配 | 是 |
Invalid idcard number | 查无此身份证号 | 否 |
Gongan service timeout | 接口获取超时 | 否 |
Gongan service is unavailable temporarily | 服务不可用 | 否 |
Network error | 网络错误 | 否 |
Unknown error | 未知错误 | 否 |
注:和/identity/selfie/idnumber_verification接口不同,此接口数据源返回值reason
为Gongan photo doesn’t exist、Name and idcard number doesn’t match、Invalid idcard number返回状态码为400
输出报错样例:
{
"status": "PHOTO_SERVICE_ERROR",
"reason": "Gongan photo doesn’t exist",
"request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e"
}
4.如果已经成功调用数据源接口,但接下来的步骤出错(错误码为400,status
为NO_FACE_DETECTED、WRONG_LIVENESS_DATA),我们会在错误响应的JSON中返回接口的状态。字段说明如下:
identity
的结构描述:
字段 | 类型 | 描述 |
---|---|---|
validity | boolean | 身份证和姓名经过接口验证是否匹配。匹配为 true ,不匹配为 false |
photo_id | string | 后台预留照片的 ID。后台无该身份信息对应的照片时该值为 null |
reason | string | 接口返回描述信息,正常为Gongan status OK |
reason 字段 |
描述 | 是否收费 |
---|---|---|
poor picture quality | 图片质量差 | 是 |
参考样例如下:
{
"status": "NO_FACE_DETECTED",
"image": "liveness",
"request_id": "TIDc5721b2b7cdb488fafb1e065c4c40619",
"identity": {
"validity": true,
"photo_id": "6963927a2b1e4fbc9abd9ff15638a2b5",
"reason": "Gongan status OK"
}
}
5.输入示例
cURL 样例
curl -X POST "https://cloudapi.linkface.cn/identity/liveness_idnumber_verification?api_id=ID&api_secret=SECRET" \
-F liveness_data_file=@/PATH/TO/PROTOBUF -F id_number=NUMBER -F name=NAME
HTTPie 样例
http -f POST "https://cloudapi.linkface.cn/identity/liveness_idnumber_verification?api_id=ID&api_secret=SECRET" \
liveness_data_file@/PATH/TO/PROTOBUF id_number=NUMBER name=NAME
C++ 样例
#include <iostream>
#include <cstring>
#include <exception>
#include <curl/curl.h>
#include <json/json.h>
using namespace std;
size_t callback(char *ptr, size_t size, size_t nmemb, string &stream){
size_t sizes = size*nmemb;
string temp(ptr,sizes);
stream += temp;
return sizes;
}
int main( int argv, char * argc[] ){
CURL *curl;
CURLM *multi_handle;
CURLcode res;
long code;
string stream;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL;
struct curl_slist *headerlist = NULL;
try{
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if( curl ){
curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"api_id",
CURLFORM_COPYCONTENTS, "ID",CURLFORM_END);
curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"api_secret",
CURLFORM_COPYCONTENTS, "SECRET",CURLFORM_END);
curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"id_number",
CURLFORM_COPYCONTENTS, "NUMBER",CURLFORM_END);
curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"name",
CURLFORM_COPYCONTENTS, "NAME",CURLFORM_END);
curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"liveness_data_file",
CURLFORM_FILE, argc[1], CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_URL, "https://cloudapi.linkface.cn/identity/liveness_idnumber_verification");
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
res = curl_easy_perform(curl);
if( res != CURLE_OK ){
cout<<"curl_easy_perform() failed:"<<curl_easy_strerror(res)<<endl;
return -1;
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
Json::Value res_data;
Json::Reader *reader = new Json::Reader(Json::Features::strictMode());
if(!reader->parse(stream, res_data)){
cout<<"parse error";
return -1;
}
cout<<"HTTP Status Code:"<<code<<endl;
cout<<res_data<<endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}catch(exception &ex){
cout<<"curl exception:"<<ex.what()<<endl;
}
}
Java 样例
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class httpClientPost {
public static final String api_id = "ID";
public static final String api_secret = "SECRET";
public static final String filepath = "C:/Users/liveness.protobuf";//活体protobuf文件
public static final String POST_URL = "https://cloudapi.linkface.cn/identity/liveness_idnumber_verification";
public static final String username = "name";//姓名
public static final String id_number = "number";//身份证号
public static void HttpClientPost() throws ClientProtocolException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost post = new HttpPost(POST_URL);
StringBody id = new StringBody(api_id);
StringBody secret = new StringBody(api_secret);
StringBody name = new StringBody(username,Charset.forName("UTF-8"));
StringBody number = new StringBody(id_number);
FileBody fileBody = new FileBody(new File(filepath));
MultipartEntity entity = new MultipartEntity();
entity.addPart("api_id", id);
entity.addPart("api_secret", secret);
entity.addPart("name", name);
entity.addPart("id_number", number);
entity.addPart("liveness_data_file", fileBody);
post.setEntity(entity);
HttpResponse response = httpclient.execute(post);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entitys = response.getEntity();
BufferedReader reader = new BufferedReader(
new InputStreamReader(entitys.getContent()));
String line = reader.readLine();
System.out.println(line);
}else{
HttpEntity r_entity = response.getEntity();
String responseString = EntityUtils.toString(r_entity);
System.out.println("错误码是:"+response.getStatusLine().getStatusCode()+" "+response.getStatusLine().getReasonPhrase());
System.out.println("出错原因是:"+responseString);
//你需要根据出错的原因判断错误信息,并修改
}
httpclient.getConnectionManager().shutdown();
}
public static void main(String[] args) throws ClientProtocolException, IOException {
HttpClientPost();
}
}
Ruby 样例
require 'net/http/post/multipart'
require 'json'
begin
uri = URI.parse('https://cloudapi.linkface.cn/identity/liveness_idnumber_verification')
File.open("liveness.protobuf") do |protoFile|
req = Net::HTTP::Post::Multipart.new uri.path,
"liveness_data_file" => UploadIO.new(protoFile, "application/octet-stream", "livenss.protobuf"),
"api_id" => "ID",
"api_secret" => "SECRET",
"id_number" => "NUMBER",
"name" => "NAME"
res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
http.request(req)
end
result = JSON.parse(res.body)
puts result
end
rescue Exception => e
puts e.message
end
Python 样例
我们提供的样例支持 Python 2.7 & 3.4–3.7 和 PyPy,其他版本暂不提供,需要您查阅相关资料。
import requests
try:
host = 'https://cloudapi.linkface.cn'
url = host + '/identity/liveness_idnumber_verification'
files = {'liveness_data_file': open('/liveness/data/file/path', 'rb')}
data = {'api_id': 'ID','api_secret': 'SECRET','id_number': 'ID_NUMBER','name':'NAME'}
response = requests.post(url, files = files, data = data)
result = response.json()
print result
except Exception as e:
print("type error: " + str(e))
PHP 样例
我们提供的样例是基于 PHP 5.5 与 PHP 5.6 两个版本,其他版本暂不提供,需要您查阅相关资料。
以下样例是基于 PHP 5.5 版本的。
<?php
$testurl = 'https://cloudapi.linkface.cn/identity/liveness_idnumber_verification';
$filePath = 'C:/Users/liveness.protobuf'; //活体protobuf文件
$fileContent = '@' . realpath($filePath);
$post_data = array ('api_id' => 'ID','api_secret' => 'SECRET','id_number' => 'NUMBER',
'name' => 'NAME','liveness_data_file' => $fileContent);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $testurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//您可以根据需要,决定是否打开SSL验证
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
var_dump($output);
curl_close($ch);
?>
以下样例是基于 PHP 5.6 版本的。
<?php
$testurl = 'https://cloudapi.linkface.cn/identity/liveness_idnumber_verification';
$filePath = 'C:/Users/liveness.protobuf'; //活体protobuf文件
$fileContent = new \CURLFile($filePath);
$post_data = array ('api_id' => 'ID','api_secret' => 'SECRET','id_number' => 'NUMBER',
'name' => 'NAME','liveness_data_file' => $fileContent);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $testurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//您可以根据需要,决定是否打开SSL验证
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
var_dump($output);
curl_close($ch);
?>