接口文檔的正確使用-記錄自己使用接口文檔中的坑

昨天接口調試遇到的坑

下面是需求文檔

調用地址
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 成功更新廁所數量

這裏寫圖片描述

這裏要做的是根據公廁的使用情況,把數據推到服務端,好吧,我承認我是小白, 來來來,分析一下並且總結下

  1. 文檔規範
    這裏出現了一個節點的概念,也就是傳入參數的多維數組的鍵值 , 轉化爲json也是一個屬性名,只不過書面上沒見過這種寫法,所以不太懂了

  2. 鑑權問題
    這個問題是第二次遇見了,但是上次沒有搞懂,這次也慘淡收場
    今天就好好分析下原因了
    首先是生成query_string值的問題,如上面所示, 要求query_string的格式爲 path+ ‘?’ + url參數(參數進行url編碼),爲了必變出現特殊字符串
    這裏使用的是rawurlencode進行編碼的

    1. urlencode:返回字符串,此字符串中除了 -_. 之外的所有非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數,空格則編碼爲加號(+)。此編碼與 WWW 表單 POST 數據的編碼方式是一樣的,同時與 application/x-www-form-urlencoded 的媒體類型編碼方式一樣。由於歷史原因,此編碼在將空格編碼爲加號(+)方面與 RFC1738 編碼
    2. rawurlencode:返回字符串,此字符串中除了 -_. 之外的所有非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數。這是在 RFC 1738 中描述的編碼,是爲了保護原義字符以免其被解釋爲特殊的 URL 定界符,同時保護 URL 格式以免其被傳輸媒體(像一些郵件系統)使用字符轉換時弄亂。
  3. 包體
    說到這,可以看出我的基礎有多差了,我對包體竟然不知道是什麼東西,其實也就是post的數據,但是和對面的技術交流中,對面說包體,我說是不是傳遞的參數,我兩個都都是一臉懵逼,好吧,是我的錯.一會再好好看看http

  4. 生成sign值
    對傳遞的url參數的鍵值進行遍歷編碼,然後拼接包體(下面要講),再進行base64編碼生成一個sign值 , 是url參數編碼之後,再拼接上包體生成一個sign值
  5. 請求的url
    請求的url是求口url拼接上上面的參數再額外拼接上sigin值 , 對其進行post請求
    1. 請求的包體
      也就是post過去的數據了啊 … 說這麼專業不懂啊 , 但是這裏遇到一個坑,以前curl post數據時,直接進行把數據以數組的形式傳遞就可以了,但是這次竟然不行,好吧 , 人家要的是json , 但是我發送的是數組,哎,肯定錯了啊,昨天我才知道,curl post數據竟然還有兩種情況 , 努力吧老年人,不知道的東西還是太多太多
    2. curl 的坑
      剛開始curl模擬請求的時候,沒有任何結果,不知道怎麼回事,請了個大神幫我調.他還是有經驗,先是打印錯誤報告,我咋沒想到呢…我是無腦的點擊鼠標 ….
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);
    }
發佈了76 篇原創文章 · 獲贊 30 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章