在Postman中引用JS库

前言

在做接口测试时,出于安全因素,请求参数需要做加密或者加上签名才能正常请求,例如:根据填写的请求参数进行hash计算进行签名。postman作为主流的接口调试工具也是支持请求预处理的,即在请求前使用JavaScript脚本对参数进行一些预处理然后再进行引用。

背景

一般接口都是用Java语言写的,所以其加密算法也是Java语言写的,加密过程中可能会涉及到引用了Java相关的类库,所以在postman中进行涉及加密接口的请求时,需要先将Java加密算法转换成JavaScript代码,在转换过程中就可能引用到JS的类库。那么怎么在Postman中引用JS类库呢?假设我们要在Postman中引用CryptoJS库。

将Java代码转换为js代码

有以下Java签名算法

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";
    //请求参数信息
    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);
}
}

转换为JS代码:

javascript 复制代码
// 引入 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;
}

// 测试用例
(function main() {
    const channelId = '12345678';
    const pid = 'beijing';
    const time = Date.now();
    const brand = 'Apple';
    const modal = 'iPhone 15 pro';
    const key = '123dzW127725c47534bdeqf6726de68z';

    // 请求参数信息
    const paramMap = {
        modelCode: brand + ' ' + modal,
        channelId: channelId,
        pid: pid,
        time: time
    };

    const signature = veritySign(paramMap, key);
    console.log('Signature:', signature);
})();

请注意以下几点:

  1. CryptoJS: 我们假设您已经在项目中包含了 CryptoJS 库,并且可以通过 require 或者 script标签引入它。
  2. Date.now(): JavaScript 中获取当前时间戳的方法与 Java 中System.currentTimeMillis() 相当。
  3. SortedMap: 在 JavaScript 中,我们使用
    Object.entries 和 for...of 循环来遍历对象的键值对。由于 JavaScript 的 Object.entries返回的数组默认就是按添加顺序排序的,因此不需要额外的排序。
  4. 编码问题: JavaScript中处理字符串编码通常不是问题,因为字符串是以 UTF-16 编码的,但如果您需要明确地处理编码问题,可以使用 TextEncoder类(在现代浏览器中可用)或者第三方库如 Buffer (Node.js 中可用)。
  5. 测试用例: 我将 Java 中的main 方法转换成了一个立即执行的函数表达式 (IIFE),用于测试 veritySign 函数。

您可以将这段代码放在一个 HTML 文件中并运行它,或者在 Node.js 环境中运行它,只要确保 CryptoJS 库已经被正确加载。

这里是修改后的代码,用于在 Postman 的预请求脚本中使用 CryptoJS:

在postman中进行引用

在 Postman 的预请求脚本中,您不能使用 window 对象(浏览器对象),因为预请求脚本是在 Node.js 环境中运行的,而不是在浏览器环境中运行的。因此,window 对象是不可用的。您应该直接使用 require 来加载 CryptoJS 模块。

步骤 1: 安装 CryptoJS

首先,确保您已经在本地机器上安装了 Node.js 和 npm。然后,安装 CryptoJS 模块:

bash 复制代码
npm install crypto-js

步骤 2: 在 Postman 中引用 CryptoJS

接下来,在 Postman 的预请求脚本中引用 CryptoJS:

测试脚本需要做一点点改动,需要将签名字符串设置成postman全局变量在请求体中引用:

javascript 复制代码
// 将生成的签名存储到全局变量中
pm.globals.set("sign", sign);

postman完整pre request代码

javascript 复制代码
// 引入 CryptoJS 模块
var CryptoJS = require('crypto-js');

// 修改后的 veritySign 函数
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;
}

// 初始化参数
    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
};

// 调用 veritySign 函数
let sign = veritySign(paramMap, key);

// 将生成的签名存储到全局变量中
pm.globals.set("sign", sign);

注意事项

  1. 确保 CryptoJS 已经安装:确保您已经在本地机器上安装了 CryptoJS 模块。
  2. 使用 require 导入模块 :在 Postman 的预请求脚本中使用 require 来导入 CryptoJS 模块。
  3. 异步问题 :上述代码中的 veritySign 函数是同步的,这意味着它会在 Postman 的预请求脚本中立即执行。如果您需要处理异步操作,可以使用回调函数或 Promise 来实现。

按照上述步骤,您应该能够在 Postman 的预请求脚本中使用 CryptoJS 并生成所需的签名。

测试

打开postman控制台,点击待测接口并请求,查看控制台日志打印:

可以看到请求签名是OK的,这样我们就能在请求body中引用了:

相关推荐
WTSolutions2 分钟前
探索 Excel-to-JSON:高效数据转换的利器
javascript
前端小巷子10 分钟前
浏览器的组成部分与工作原理
前端·javascript·面试
Dream耀10 分钟前
解密JavaScript的this绑定规则
前端·javascript·架构
中微子13 分钟前
深入理解 JavaScript 变量作用域与 this 机制:从基础到最佳实践
javascript
Sparkxuan17 分钟前
Map、Set、WeakMap 和 WeakSet
前端·javascript
快起来别睡了17 分钟前
var、let、const傻傻分不清,一篇文章告诉你它们的区别!
前端·javascript·程序员
示示猫32 分钟前
Wasm是什么、不是什么
javascript·webassembly
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | FAQ Collapse(问题解答折叠面板)
前端·javascript·css·vue·tailwindcss
小丫头呀2 小时前
vue中的v-model指令和组件通信机制
javascript·vue.js
前端呆猿2 小时前
AJAX、Axios 与 Fetch:现代前端数据请求技术对比
前端·javascript·ajax