昨天接口调试遇到的坑
下面是需求文档
调用地址
post 请求
https://apitest.bdc.abc.com/toilet/status/report
请求协议
参数名 必选 类型 说明
time Yes int 更新时间,Unix时间戳
male Yes Stat 男厕所状态信息
female Yes Stat 女厕所状态信息
third Yes Stat 第三卫生间
Stat节点
参数名 必选 类型 说明
in Yes int 入流量
out Yes int 出流量
stay Yes int 驻留人数
响应参数
参数名 类型 说明
code int64 返回码:0:成功,其他:失败
msg string 返回信息
data 对象 返回的数据对象
Data节点
参数名 必选 类型 说明
total Yes int 请求更新厕所数量
num Yes int 成功更新厕所数量
这里要做的是根据公厕的使用情况,把数据推到服务端,好吧,我承认我是小白, 来来来,分析一下并且总结下
文档规范
这里出现了一个节点的概念,也就是传入参数的多维数组的键值 , 转化为json也是一个属性名,只不过书面上没见过这种写法,所以不太懂了
鉴权问题
这个问题是第二次遇见了,但是上次没有搞懂,这次也惨淡收场
今天就好好分析下原因了
首先是生成query_string值的问题,如上面所示, 要求query_string的格式为 path+ ‘?’ + url参数(参数进行url编码),为了必变出现特殊字符串
这里使用的是rawurlencode进行编码的
包体
说到这,可以看出我的基础有多差了,我对包体竟然不知道是什么东西,其实也就是post的数据,但是和对面的技术交流中,对面说包体,我说是不是传递的参数,我两个都都是一脸懵逼,好吧,是我的错.一会再好好看看http
if (curl_errno($ch)) {
echo '错误:'.curl_error($ch);
}
看到报错之后,发现了问题所在 php curl常见错误:SSL错误、bool(false)
我还以为没有装curl扩展呢,但是确认了下,是装了的,再仔细看原来是ssl证书的问题,所以要绕过ssl证书检测
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
好了,再请求接口终于能通了, 下面是总结的代码
public function actionLink()
{
$url = "https://apitest.bdc.***.com";
$path = '/toilet/status/report';
$id = 1231644;
$devid = '***';
$device_secret = "**";
$nonce = time() . rand(1000,9999);
$time = time() ;
$query = array(
'mode' => 2,
'id' => $id,
'devid' => $devid,
'nonce' => $nonce,
'timestamp' => $time,
);
$post_data = [
'time' => $time,
'male' => [
'in'=>1,
'out'=>2,
'stay'=>66
],
'female' => [
'in'=>1,
'out'=>2,
'stay'=>3
],
'stay' => [
'in'=>1,
'out'=>2,
'stay'=>66
],
];
ksort($query, SORT_STRING);
$data = '';
foreach($query as $key => $value) {
$data .= rawurlencode($key).'='.rawurlencode($value).'&';
}
$data = rtrim($data, '&');
$param = $path.'?'.$data . json_encode($post_data);
$query['sign'] = base64_encode(hash_hmac('sha1', $data , $device_secret, true));
$url = $url . $path.'?'.$data . '&sign=' .urlencode($query['sign']);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
if (curl_errno($ch)) {
echo '错误:'.curl_error($ch);
}
curl_close($ch);
print_r($output);
}