JMeter處理接口簽名(sign)


先貼腳本, 大神請直取

  • 新建線程組 → http取樣器 → 前置處理器 → bean shell 預處理程序

    import org.apache.commons.codec.digest.DigestUtils; 
    import java.util.Date;
    //沒有第三方jar包,請放心 import
      
    Date date = new Date();
    //將時間戳截取到秒的量級(長度共10位),大神可以考慮地板除,弟中弟請當沒看見
    String timestamp = String.valueOf(date.getTime()/1000);
    //將時間戳賦值給ts變量,方便以 ${ts} 的方式引用
    vars.put("ts",timestamp);
      
    //此處的SPhone的值可以用csv參數化
    String data = "{\"SPhone\":\"18662255783\",\"EType\":0}";
    
    String key = "a323f9b6-1f04-420e-adb9-b06ty67b0e63";
    
    String bsign = "z417App" + timestamp + data + key;
    
    //MD5加密賦值給sign變量
    vars.put("sign",DigestUtils.md5Hex(bsign));
    

小白請從這里看起

REST api大多會傳sign(簽名)字段,各接口對sign的內容、方式可能不一樣,但一般模式都是從接口的入參中選擇部分內容組成一個字符串,然后再拼接一個secretKeyappKey(秘鑰,值固定), 最后對這個拼接起來的字符串進行MD5的運算, 將結果賦值給sign; 完整規范的接口文檔都會有sign的算法描述。

解題思路

  1. 找到簽名算法:接口文檔為准,secretKey 或 appKey 可以問開發要;

  2. 接口的傳入的參數不改變,則sign的值就不變:利用這點可以先用接口測試工具(如postman)調試下接口, 在線MD5請移步站長工具

  3. 接口手動調通了,接下來翻譯到工具的腳本語言中:說的比較晦澀,繼續往下看吧;

  4. 特別注意:如果待簽名的內容中有中文,需要特別處理下!!踩過坑(這部分會在loadrunner如何處理sign的博客中記錄,先挖個坑,以后填)。

接口入參示例

  • 以下是一個傳入手機號獲取短信驗證碼的請求消息

    {
        "AppKey": "z417App",
        "AppVer": "1.0.0",
        "Data": "{\"SPhone\":\"18662255783\",\"EType\":0}",
        "DeviceName": "web",
        "DeviceType": "web",
        "Lang": "CN",
        "Sign": "8011fd9bdacd3372103053b43bef76e7",
        "TimeStamp": 1560584745
    }
    

初步分析

  1. 這是一串json消息:post方式發送

  2. 里面套的Data字段的值有點像json:Data的值是個字符串,不是內層 json

  3. SPhone的值是字符串格式的電話號碼:可能是個動態變化的,得用參數化處理下,使它變化起來

  4. sign應該就是今天的主角:sign的算法請仔細閱讀接口文檔,實在看不懂就問開發

  5. TimeStamp時間戳:一個精確到秒的時間戳

確定可能會動態變換的入參

  1. SPhone字段

  2. Sign字段

  3. TimeStamp字段

簽名算法

AppKey + TimeStamp + Data + secretKey 的值拼接在一起組成一個新的字符串,對該字符串進行MD5(32位[小])的運算。(tps:站長工具)

  • 舉個不能吃的栗子:
    AppKey 的值是 "z417App"

    TimeStamp 的值是 1560584745

    Data 的值是 "{\"SPhone\":\"18662255783\",\"EType\":0}"

    secretKey 的值是 "a323f9b6-1f04-420e-adb9-b06ty67b0e63"

    ⑤ 拼接成一個字符串:

    z417App1560584745{\"SPhone\":\"18662255783\",\"EType\":0}a323f9b6-1f04-420e-adb9-b06ty67b0e63
    

    ⑥ MD5運算后的值:8011fd9bdacd3372103053b43bef76e7 → 就可以賦給Sign了

  • 再舉個不能吃的栗子:(其他簽名算法)

從所有入參中篩選出參數的值不為空(null,"")的集合,將集合中的參數名按照ASCII碼從小到大排序(像英語詞典), 使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串(sign字段不參與拼接),假設是str1;在str1最后拼接上key=secretKey,得到更長的一個字符串,假設是str2。對str2進行MD5運算,再將得到的字符串轉換為大寫

  • 入參舉例:

    {
        "appid": "wxd930u",
        "mch_id": 10100,
        "device_info": 100,
        "body": "{\"EType\":0}",
        "DeviceType": "",
        "nonce_str": "ibuaiVc",
        "sign": "CD198C36632A274C49E5F2F028FA257C",
        "source": null
    }
    
  • 第一步:按字典序對有值的入參、按url鍵值對的方式進行拼接

    String str1 = "appid=wxd930u&body={\"EType\":0}&device_info=100&mch_id=10100&nonce_str=ibuaiVc";
    
  • 第二步:拼接API密鑰(secretKey的值:a323f9b6):

    String str2 = str1 + "&key=a323f9b6";
    
  • 第三步:簽名MD5(32位[大],可用站長工具)

    /** 
    * 注意java中有自帶的MD5方法,是16位以16個元素的形式返回值,大神請自己寫,弟中弟請用已有的jar
    * md5hex是以32位16進制的小寫字符串形式返回
    */
    String sign = DigestUtils.md5Hex(str2).toUpperCase();
    // 即 sign = "CD198C36632A274C49E5F2F028FA257C"
    

再看bean shell腳本

import org.apache.commons.codec.digest.DigestUtils; // DigestUtils類中有md5算法 
import java.util.Date; // Date類中有獲取當前時間戳方法
//沒有第三方jar包,請放心 import

Date date = new Date(); // 創建Date對象,取名叫date
//將時間戳截取到秒的量級(長度共10位),大神可以考慮地板除,弟中弟請當沒看見
String timestamp = String.valueOf(date.getTime()/1000);
//將時間戳賦值給ts變量,方便以 ${ts} 的方式引用
vars.put("ts",timestamp);

//此處的SPhone的值可以用csv參數化
String data = "{\"SPhone\":\"18662255783\",\"EType\":0}";
String key = "a323f9b6-1f04-420e-adb9-b06ty67b0e63"; // 要拼接的secretKey
String bsign = "z417App" + timestamp + data + key; // 拼接

//MD5加密后,賦值給sign變量
vars.put("sign",DigestUtils.md5Hex(bsign));

在http的取樣器中使用 ts 和 sign 的值

{
    "AppKey": "z417App",
    "AppVer": "1.0.0",
    "Data": "{\"SPhone\":\"18662255783\",\"EType\":0}",
    "DeviceName": "web",
    "DeviceType": "web",
    "Lang": "CN",
    "Sign": "${sign}",
    "TimeStamp": ${ts}
}

問題思考

  1. 前面的例子是建立在request body不變的情況下才能成立,如果request body變化呢?比如對手機號(Sphone)做了參數化。處理方式有兩種,請戳 jmeter處理動態的簽名(sign)內容

  2. 歡迎交流指正


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM