如何做網(wǎng)站的書(shū)籍百度廣告推廣怎么收費(fèi)
前言
在做接口測(cè)試時(shí),出于安全因素,請(qǐng)求參數(shù)需要做加密或者加上簽名才能正常請(qǐng)求,例如:根據(jù)填寫(xiě)的請(qǐng)求參數(shù)進(jìn)行hash計(jì)算進(jìn)行簽名。postman作為主流的接口調(diào)試工具也是支持請(qǐng)求預(yù)處理的,即在請(qǐng)求前使用JavaScript腳本對(duì)參數(shù)進(jìn)行一些預(yù)處理然后再進(jìn)行引用。
背景
一般接口都是用Java語(yǔ)言寫(xiě)的,所以其加密算法也是Java語(yǔ)言寫(xiě)的,加密過(guò)程中可能會(huì)涉及到引用了Java相關(guān)的類庫(kù),所以在postman中進(jìn)行涉及加密接口的請(qǐng)求時(shí),需要先將Java加密算法轉(zhuǎn)換成JavaScript代碼,在轉(zhuǎn)換過(guò)程中就可能引用到JS的類庫(kù)。那么怎么在Postman中引用JS類庫(kù)呢?假設(shè)我們要在Postman中引用CryptoJS庫(kù)。
將Java代碼轉(zhuǎn)換為js代碼
有以下Java簽名算法
package org.example;import org.apache.commons.codec.digest.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.Map.Entry;/**Unit test for simple App. */
public class AppTest
{
public static String veritySign(SortedMap<String, Object> parameters, String key) {StringBuffer sbkey = new StringBuffer();Set es = parameters.entrySet();Iterator it = es.iterator();String md5a;while (it.hasNext()) {Entry entry = (Entry) it.next();md5a = (String) entry.getKey();Object v = entry.getValue();if (null != v && !"".equals(v)) {sbkey.append(md5a + "=" + v + "&");}}sbkey = sbkey.append("key=" + key);String sbString = sbkey.toString();md5a = "";String content = sbkey.toString();char[] chars = content.toCharArray();String charset = "utf-8";int sum = 0;char[] var12 = chars;int i = chars.length;for (int var14 = 0; var14 < i; ++var14) {char aChar = var12[var14];sum += Integer.valueOf(aChar);}int num = sum % 3 + 3;for (i = 0; i < num; ++i) {try {content = DigestUtils.md5Hex(content.getBytes(charset)).toUpperCase();} catch (UnsupportedEncodingException var16) {var16.printStackTrace();}}md5a = content;System.out.println(md5a);return md5a;
}public static void main(String[] args) {String channelId = "12345678";String pid = "beijing";Long time = System.currentTimeMillis();String brand="Apple";String modal="iPhone 15 pro";String key = "123dzW127725c47534bdeqf6726de68z";//請(qǐng)求參數(shù)信息SortedMap<String, Object> paramMap = new TreeMap<>();paramMap.put("modelCode", brand + " " + modal);paramMap.put("channelId", channelId);paramMap.put("pid", pid);paramMap.put("time", time);veritySign(paramMap, key);
}
}
轉(zhuǎn)換為JS代碼:
// 引入 CryptoJS 模塊
function veritySign(parameters, key) {let sbkey = '';for (const [keyParam, value] of Object.entries(parameters)) {if (value !== null && value !== '') {sbkey += keyParam + '=' + value + '&';}}sbkey += 'key=' + key;let content = sbkey;let chars = content.split('');let sum = 0;for (let i = 0; i < chars.length; i++) {let aChar = chars[i];sum += aChar.charCodeAt(0);}let num = sum % 3 + 3;for (let i = 0; i < num; i++) {try {content = CryptoJS.MD5(content).toString().toUpperCase();} catch (error) {console.error(error);}}let md5a = content;console.log(md5a);return md5a;
}// 測(cè)試用例
(function main() {const channelId = '12345678';const pid = 'beijing';const time = Date.now();const brand = 'Apple';const modal = 'iPhone 15 pro';const key = '123dzW127725c47534bdeqf6726de68z';// 請(qǐng)求參數(shù)信息const paramMap = {modelCode: brand + ' ' + modal,channelId: channelId,pid: pid,time: time};const signature = veritySign(paramMap, key);console.log('Signature:', signature);
})();
請(qǐng)注意以下幾點(diǎn):
- CryptoJS: 我們假設(shè)您已經(jīng)在項(xiàng)目中包含了 CryptoJS 庫(kù),并且可以通過(guò) require 或者 script標(biāo)簽引入它。
- Date.now(): JavaScript 中獲取當(dāng)前時(shí)間戳的方法與 Java 中System.currentTimeMillis() 相當(dāng)。
- SortedMap: 在 JavaScript 中,我們使用
Object.entries 和 for…of 循環(huán)來(lái)遍歷對(duì)象的鍵值對(duì)。由于 JavaScript 的 Object.entries返回的數(shù)組默認(rèn)就是按添加順序排序的,因此不需要額外的排序。 - 編碼問(wèn)題: JavaScript中處理字符串編碼通常不是問(wèn)題,因?yàn)樽址且?UTF-16 編碼的,但如果您需要明確地處理編碼問(wèn)題,可以使用 TextEncoder類(在現(xiàn)代瀏覽器中可用)或者第三方庫(kù)如 Buffer (Node.js 中可用)。
- 測(cè)試用例: 我將 Java 中的main 方法轉(zhuǎn)換成了一個(gè)立即執(zhí)行的函數(shù)表達(dá)式 (IIFE),用于測(cè)試 veritySign 函數(shù)。
您可以將這段代碼放在一個(gè) HTML 文件中并運(yùn)行它,或者在 Node.js 環(huán)境中運(yùn)行它,只要確保 CryptoJS 庫(kù)已經(jīng)被正確加載。
這里是修改后的代碼,用于在 Postman 的預(yù)請(qǐng)求腳本中使用 CryptoJS:
在postman中進(jìn)行引用
在 Postman 的預(yù)請(qǐng)求腳本中,您不能使用 window 對(duì)象(瀏覽器對(duì)象),因?yàn)轭A(yù)請(qǐng)求腳本是在 Node.js 環(huán)境中運(yùn)行的,而不是在瀏覽器環(huán)境中運(yùn)行的。因此,window 對(duì)象是不可用的。您應(yīng)該直接使用 require 來(lái)加載 CryptoJS 模塊。
步驟 1: 安裝 CryptoJS
首先,確保您已經(jīng)在本地機(jī)器上安裝了 Node.js 和 npm。然后,安裝 CryptoJS 模塊:
npm install crypto-js
步驟 2: 在 Postman 中引用 CryptoJS
接下來(lái),在 Postman 的預(yù)請(qǐng)求腳本中引用 CryptoJS:
測(cè)試腳本需要做一點(diǎn)點(diǎn)改動(dòng),需要將簽名字符串設(shè)置成postman全局變量在請(qǐng)求體中引用:
// 將生成的簽名存儲(chǔ)到全局變量中
pm.globals.set("sign", sign);
postman完整pre request代碼
// 引入 CryptoJS 模塊
var CryptoJS = require('crypto-js');// 修改后的 veritySign 函數(shù)
function veritySign(parameters, key) {let sbkey = '';for (const [key, value] of Object.entries(parameters)) {if (value !== null && value !== '') {sbkey += key + '=' + value + '&';}}sbkey += 'key=' + key;let sbString = sbkey;let content = sbkey;let chars = content.split('');let sum = 0;for (let i = 0; i < chars.length; i++) {let aChar = chars[i];sum += aChar.charCodeAt(0);}let num = sum % 3 + 3;for (let i = 0; i < num; i++) {try {content = CryptoJS.MD5(content).toString().toUpperCase();} catch (error) {console.error(error);}}let md5a = content;console.log(md5a);return md5a;
}// 初始化參數(shù)const channelId = '12345678';const pid = 'beijing';const time = Date.now();const brand = 'Apple';const modal = 'iPhone 15 pro';const key = '123dzW127725c47534bdeqf6726de68z';let paramMap = {modelCode: brand + ' ' + modal,channelId: channelId,pid: pid,time: time
};// 調(diào)用 veritySign 函數(shù)
let sign = veritySign(paramMap, key);// 將生成的簽名存儲(chǔ)到全局變量中
pm.globals.set("sign", sign);
注意事項(xiàng)
- 確保 CryptoJS 已經(jīng)安裝:確保您已經(jīng)在本地機(jī)器上安裝了 CryptoJS 模塊。
- 使用
require
導(dǎo)入模塊:在 Postman 的預(yù)請(qǐng)求腳本中使用require
來(lái)導(dǎo)入 CryptoJS 模塊。 - 異步問(wèn)題:上述代碼中的
veritySign
函數(shù)是同步的,這意味著它會(huì)在 Postman 的預(yù)請(qǐng)求腳本中立即執(zhí)行。如果您需要處理異步操作,可以使用回調(diào)函數(shù)或 Promise 來(lái)實(shí)現(xiàn)。
按照上述步驟,您應(yīng)該能夠在 Postman 的預(yù)請(qǐng)求腳本中使用 CryptoJS 并生成所需的簽名。
測(cè)試
打開(kāi)postman控制臺(tái),點(diǎn)擊待測(cè)接口并請(qǐng)求,查看控制臺(tái)日志打印:
可以看到請(qǐng)求簽名是OK的,這樣我們就能在請(qǐng)求body中引用了: