最近一段时间,对接接口有4,5家左右,每家的验证方式各有千秋,今天总结一下各个验证。
接口推送数据以下用Data代表推送的二维数组数据包,url代表推送线索的链接地址。
一·、
解:
- 最简单的文档,透漏出最难的问题。
- 正常的curl去传递接口,发现根本不对,提示我data缺失,明明传递了。
- 问题在这:key(****************)代表的是按照 k1=v1&k2=v2 拼接再加$key,对http请求header头部处理Content-Type:application/x-www-form-urlencoded (把form数据封装到http body中,然后发送到server)
- 代码如下:
//数据包json和base64的处理
$post_data['apiData'] = base64_encode(json_encode($Data));
//$key跟第三方业务要的
$post_data['sign'] = md5($post_data['apiData'].$key);
$header = array('Accept:text/plain;charset=utf-8', 'Content-Type:application/x-www-form-urlencoded', 'charset=utf-8', 'Expect:', 'Connection: Close');
$response = $this->curl($url, 'POST', $post_data, $header);
二、
解:
- 这个和第一个差不多也需要键值对key=value&处理,但是这个需要一个Sign签名。
- 签名规则:根据字典排序,然后用key=value&方式拼接好再加上公共参数&key=key,接着MD5中32位加密转大写即可。
- 代码如下:
//业务获取
$data['app_type'] = $app_type;
//时间戳
$data['time'] = strtotime(date('Y-m-d H:i:s'));
//ASCII码排序
ksort($post_data);
//转url格式
$str = "";
foreach ($post_data as $key => $val){
$str = $str. $key . "=" . $val."&";
}
//拼接
$str_temp = $str . 'app_key='. $this->app_key;
//md5 32位加密 字符大写
$sign = mb_strtoupper(md5($str_temp),'utf-8');
$data['sign'] = $sign;
$response = $this->curl($url, 'POST', $post_data);
三、
解:
- 全部参数任何调用接口都必须是json串,请求header:Content-Type:application/json接口有当时没看到…
- 同理也是根据appid和key秘钥获取一个Token,这个token不是签名,而是放入header中跟着地址去请求,这算是一个需要注意的地方。
- token两个小时过期,我加了一个redis缓存存放时间115分钟提前失效,(接触过一个最恶心的接口:同一个ip一个小时内只允许获取4-5次Token,那就必须存放redis处理了)
- 代码如下:
//业务获取标识&&秘钥
$post_data['appid'] = $appid;
$post_data['security'] = $security;
$redis = Business_Cache_RedisBusinessModel::getInstance();
$redis_name = $redis->getFullPre(__CLASS__);
$token_data = $redis->get($redis_name.$token_name);
$token = $this->curl($token_url,'POST',json_encode($post_data),array('Content-Type: application/json; charset=utf-8'));
//存储 115分钟
$redis->set($redis_name.$this->token_name,$token,115);
//推送线索
$header = ['Authorization:'.$token,'Content-Type: application/json; charset=utf-8'];
$response = $this->curl($url, 'POST',json_encode($data),$header);
四、
解:
- 同ASCII码排序不过keyvalue是连接一起,data数据排序完后,前后被追加app_id 和app_secret
- 代码如下:
//此代码和接口无关 yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
$contactTime = date("Y-m-d\TH:i:s", strtotime($value['order_date'])).'.000Z';
//32位随机数
$new_data['sid'] = md5(time().mt_rand(0,1000));
//当前时间 unix时间戳
$new_data['timestamp'] = strtotime(date('Y-m-d'));
//json串 JSON_UNESCAPED_UNICODE 中文不会被编码 ,不要编码Unicode.
$new_data['data'] = json_encode($data,JSON_UNESCAPED_UNICODE);
$new_data['sign_type'] = "MD5";
ksort($new_data);
$str = "";
//key value 拼接
foreach ($new_data as $key => $val){
$str = $str. $key . $val;
}
//拼接 app_id app_secret 前后夹击
$str_temp = $this->app_id .$str . $this->app_secret;
//MD5 32位加密 转小写(和上边的不同,上边是转写)
$sign = mb_strtolower(md5($str_temp));
//签名获取成功 准备去推送线索
$new_data['sign'] = $sign;
$new_data['app_id'] = $app_id;
//解json
$new_data['data'] = json_decode($new_data['data'],true);
$response = $this->curl($url, 'POST', json_encode($new_data),array('Content-Type: application/json; charset=utf-8'));
公共代码 处理curl问题
public static function curl($url, $method = 'GET', $postFields = null, $header = null) {
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );
curl_setopt ( $ch, CURLOPT_FAILONERROR, false );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt ( $ch, CURLOPT_TIMEOUT, 8 );
if (strlen ( $url ) > 5 && strtolower ( substr ( $url, 0, 5 ) ) == "https") {
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, false );
}
switch ($method) {
case 'POST' :
curl_setopt ( $ch, CURLOPT_POST, true );
if (! empty ( $postFields )) {
if (is_array ( $postFields ) || is_object ( $postFields )) {
if (is_object ( $postFields ))
$postFields = Comm_Tools::object2array ( $postFields );
$postBodyString = "";
$postMultipart = false;
foreach ( $postFields as $k => $v ) {
if ("@" != substr ( $v, 0, 1 )) { // 判断是不是文件上传
$postBodyString .= "$k=" . urlencode ( $v ) . "&";
} else { // 文件上传用multipart/form-data,否则用www-form-urlencoded
$postMultipart = true;
}
}
unset ( $k, $v );
if ($postMultipart) {
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postFields );
} else {
curl_setopt ( $ch, CURLOPT_POSTFIELDS, substr ( $postBodyString, 0, - 1 ) );
}
} else {
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postFields );
}
}
break;
default :
if (! empty ( $postFields ) && is_array ( $postFields ))
$url .= (strpos ( $url, '?' ) === false ? '?' : '&') . http_build_query ( $postFields );
break;
}
curl_setopt ( $ch, CURLOPT_URL, $url );
if (! empty ( $header ) && is_array ( $header )) {
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header );
}
$response = curl_exec ( $ch );
if (curl_errno ( $ch )) {
throw new Exception ( curl_error ( $ch ), 0 );
}
curl_close ( $ch );
return $response;
}