最近项目开发中需要结合旷世智能企业系统的人脸识别历史资料,提供的API中要求先验证登录COOKIE再查询历史资料,我首先分别验证了登陆API和查询资料API的可用性,单独验证的确都可以使用且查询资料的API必须登录之后才可以查询到资料。在两个API联合的验证过程中遇到几个问题,第一个其实是粗心忽略了登录API和查询资料API对HEADER的特殊设置,第二个是COOKIE存储方法有问题,在查询资料API找不到登录COOKIE资料,另一个是查询资料API参数传递的问题。
一.登陆API的验证
1.API说明
-
URL:
/auth/login
-
Method:
POST
-
描述:
登录并获取cookie,
后面所有的接口都需要在请求时带入此cookie
-
参数:
参数 类型 必选 描述 username str √ 邮箱 password str √ 密码 此接口需要 设置user-agent为 "Koala Admin" , 否则不能登录成功
-
返回值说明:
字段 类型 说明 avatar str 头像地址 company_id int 公司ID password_reseted bool 是否保存密码 role_id int 账号类型, 1:root, 2:管理员, 3:普通用户 username str 用户名 -
返回JSON:
{ "code": 0, "data": { "avatar": null, "company_id": 1, "id": 2, "password_reseted": true, "role_id": 2, "username": "user@megvii.com" }, "page": {} }
2.问题解决
这里利用CURL只验证登录的话只涉及到一个HEADER的设置,即接口说明中的设置user-agent为 "Koala Admin" , 否则不能登录成功
,要取回COOKIE的话我这里用了文档存储的方式。
先写出一个通用的toCurl 函数,代码如下
function toCurl($url, $method, $content, $httpHeader, $type = 'function', $cookie = '') {
$ch = curl_init($url); //请求的URL地址
//curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);//请求方式
if ($method != "GET") {
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);//请求参数,GET方式参数在URL里
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);//头文件设置
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($cookie != '') {
$cookie_jar = dirname(__FILE__) . "\\" . $cookie;
}
if ($type == "login") {
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);//COOKIE存储
}
if ($type != 'login' && $cookie != '') {
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar); //读取COOKIE,解决查询资料API未登录的前提
}
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
//curl_setopt($ch, CURLOPT_PROXY, C('CURLOPT_PROXY'));//
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, C('CURLOPT_PROXYUSERPWD'));//
$recv = curl_exec($ch);
$httpInfo = curl_getinfo($ch); //curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpInfo['http_code'] == 200) {
return $recv;
} else {
return json_encode($httpInfo);
}
}
外部登录的函数如下:
public function loginFaceUrl($innercall = false, $username = '', $password = '') {
if (!$innercall) {
$username = trim(I('post.username'));
$password = trim(I('post.password'));
}
$Util = A('Common/Util');
$param = array("username" => $username, "password" => $password);
$url = $this->http_ip . $this->login_url;
$header = array("user-agent:Koala Admin");
$loginResult = $Util->toCurl($url, "POST", $param, $header, "login", $this->cookie_name);
$login = json_decode($loginResult, true);
if ($login['code'] === 0) {//其实这里的session 和cookie 没必要做,要取回的COOKIE在上面的toCurl里已经做好
session_start();
$life_time = 12 * 60 * 60; // 30min
$cookid = setcookie(session_name(), session_id(), time() + $life_time, "/");
session("face_user", $login['data']);
}
if ($innercall) {
return $cookid;
} else {
echo json_encode($login, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
}
二.查询资料API验证
1.API说明
-
URL:
/event/events
-
Method:
GET
-
描述:
历史识别记录
-
参数:
参数 类型 必选 描述 start int 开始时间时间戳(单位秒) end int 截止时间时间戳(单位秒) user_role int 角色 {不传: 所有, 0: 员工(默认), 1: 访客, 2: VIP} user_name str 按用户名模糊查询 screen_id int 按门禁ID查询 subject_id int 按用户ID精确查询 page int 第几页 默认 1(我验证出来不能传空值,应该要写出来才对) size int 每页数量 默认 10 -
返回值:
字段 类型 说明 age float 年龄 company_id int 公司ID confidence float 相似度 gender float 性别为男的概率 photo string 抓拍照片url quality float 照片质量 screen screen模型 抓拍相机 subject subject模型 抓拍的subject对象 timestamp int 抓拍时间戳 page 参考分页信息定义 -
返回JSON:
{ "code": 0, "data": [ { "age": 35.7292, "company_id": 1, "confidence": 87.4096, "gender": 0.999992, "group": 80, "id": 2581617, "photo": "https://o7rv4xhdy.qnssl.com/@/static/upload/event/2016-05-31/452cb86b9e81add249451837637ab020482229ab.jpg", //抓拍照 "quality": 0.75279, "screen": { // 参考附录门禁模型定义 "allow_all_subjects": true, "allow_visitor": true, "box_address": "10.201.105.162", "box_heartbeat": 1464683851, "box_status": "0", "box_token": "5c31ba4b-f9c5-4b3f-bb21-fd632b73b690", "camera_address": "rtsp://10.201.105.51/live1.sdp", //抓拍的相机地址 "camera_name": "", "camera_position": "tss\u5de5\u4f4d\u6d4b\u8bd5", //抓拍的位置 "camera_status": "0", "description": null, "id": 706, "network_switcher": "", "network_switcher_status": null, "network_switcher_token": null, "screen_token": "55e6fb9d-5153-43e2-9829-1dba83e6810f", "type": 1 //抓拍设备类型 1表示相机 2表示门禁PAD }, "subject": { // 抓拍的人信息,详细请参考附录的 模型定义 "avatar": "https://o7rv4xhdy.qnssl.com/@/static/upload/avatar/2015-12-02/ed49064ca0eb5853f98b1c73a7a69cc1306c051a.jpg", "birthday": null, "come_from": "", "company_id": 1, "department": "Develop-PD", //部门 "description": "easy come\uff0ceasy go\uff01", //签名 "email": "xyb@megvii.com", "end_time": 0, "entry_date": null, "gender": 0, "id": 7021, "interviewee": "", "job_number": "135", // 工号 "name": "\u89e3\u8a00\u658c", //姓名 "password_reseted": true, "phone": "15652936120", "photos": [ //底库头像列表 { "company_id": 1, "id": 16491, "quality": 0.940321, "subject_id": 7021, "url": "https://o7rv4xhdy.qnssl.com/@/static/upload/photo/2015-11-12/bb1758c460abf63ec00bee908cf8e187f87b6547.jpg", "version": 2 } ], "purpose": 0, "remark": "", "start_time": 0, "subject_type": 0, // 人员类型 "title": "", "visit_notify": null }, "subject_id": 7021, //人员ID "timestamp": 1464683891 }, ... ], "page": { "count": 251967, // 总记录数 "current": 1, // 当前页数 "size": 10, // 每页size "total": 25197 // 总页数 } }
2.问题解决
这里登录cookie的问题在上面已经说明,这里参数传递和头文件设置给我造成了很大的困扰,在看到API说明时,我下意识的当成所有的参数为可传可不传以及没有特殊的头文件设置。解决头文件的设置问题我通过旷视智能系统找到了头文件的设置,但参数的传递是通过笨方法一个一个测试找出来到底哪个参数引起API调用总是返回出错的。
代码如下:
public function getFaceHistory($innercall = false, $paramArray = '') {
$this->loginFaceUrl(TRUE, $this->accunt, $this->password);
if (!$innercall) {
$start = empty(trim(I('post.start'))) ? date('Y-m-d 00:00:00') : trim(I('post.start'));
$end = empty(trim(I('post.end'))) ? date('Y-m-d H:i:s') : trim(I('post.end'));
$user_role = trim(I('post.role'));
$user_name = trim(I('post.name'));
$screen_id = trim(I('post.screenid'));
$subject_id = trim(I('post.subjectid'));
$page = trim(I('post.page'));
$size = empty(trim(I('post.size'))) ? $this->size : trim(I('post.size'));
if ($page == '') {//page传空值引起错误响应
$paramArray = 'start=' . strtotime($start) . '&end=' . strtotime($end) . '&user_role=' . $user_role . '&user_name=' . $user_name . '&screen_id=' . $screen_id . '&subject_id=' . $subject_id . '&size=' . $size;
} else {
$paramArray = 'start=' . strtotime($start) . '&end=' . strtotime($end) . '&user_role=' . $user_role . '&user_name=' . $user_name . '&screen_id=' . $screen_id . '&subject_id=' . $subject_id . '&page=' . $page . '&size=' . $size;
}
}
$Util = A('Common/Util');
$url = $this->http_ip . $this->face_history_url . '?' . $paramArray; //"Cookie: session=" . $sessionID,
$header = array("Accept: application/json, text/javascript");
$resultHistory = $Util->toCurl($url, "GET", $paramArray, $header, "function", $this->cookie_name);
$history = json_decode($resultHistory, true);
if ($history['code'] == 0) {
$result['code'] = $history['code'];
$result['ip'] = $this->http_ip;
$result['page'] = $history['page'];
$result['history'] = $history['data'];
} else {
$result = $history;
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}