跳到主要内容

使用 JS 类库

内置类库列表

  • Encode、Decode 库

    • crypto-js(v3.1.9-1):编码 / 解码库,常用的编码解码方式基本都有,如 Base64、MD5、SHA、HMAC、AES 等等。
      • 注意:只能 require 整个模块,不能单独 require 类库里的某个子模块。
    • atob(v2.1.2):Base64 解码
    • btoa(v1.2.1):Base64 编码
    • tv4(v1.3.0):JSONSchema 校验库
    • xml2js(v0.4.19):XML 转 JSON
  • Encode、Decode 库

    • jsrsasign(10.3.0):RSA 加密 / 解密 (Apifox 版本号 >= 1.4.5 才支持,老版本不支持)
  • 断言

    • chai (v4.2.0):BDD / TDD 断言库
  • 实用工具

    • postman-collection( v3.4.0):Postman Collection 库
    • cheerio(v0.22.0):jQuery 的一个子集
    • lodash (v4.17.11):JS 实用工具库
    • moment(v2.22.2):日期处理库 (不含 locales)
    • uuid :生成 UUID
    • csv-parse/lib/sync( v1.2.4):CSV 格式数据处理
    • iconv-lite:用于字符编码之间的转换,支持数十种字符编码格式的转换。
    • mockjs:生成随机数据,拦截 Ajax 请求。
  • JSONSchema 校验库

    • ajv(v6.6.2):JSONSchema 校验库
  • 内置 NodeJS 模块

通过 require 可以加载并使用 Apifox 内置的 JS 类库(也可以直接使用,但这样编写脚本时可能缺乏一些灵活性,具体选择取决于业务需求)。

// 引入 CryptoJS 库(可省略)
const CryptoJS = require('crypto-js');

console.log(CryptoJS.SHA256("Message"));

使用方式

使用内置类库加密、解密、编码、解码数据的常见示例参考。

SHA256 加密

// SHA256 加密,输出 Base64
// 定义要加密的消息
const message = "Hello, World!";

// 使用 SHA256 算法进行加密
const hash = CryptoJS.SHA256(message);

// 将加密结果输出为 Base64 编码
const base64Encoded = CryptoJS.enc.Base64.stringify(hash);

// 输出结果
console.log("SHA256: " + base64Encoded);

HMAC-SHA256 加密

// HMAC-SHA256 加密,输出 Base64
// 定义要加密的消息和密钥
const message = "Hello, World!";
const secretKey = "MySecretKey";

// 使用 HMAC-SHA256 算法进行加密
const hash = CryptoJS.HmacSHA256(message, secretKey);

// 将加密结果输出为 Base64 编码
const base64Encoded = CryptoJS.enc.Base64.stringify(hash);

// 输出结果
console.log("HMAC-SHA256: " + base64Encoded);

Base64 编码

// 要编码的消息
const message = "你好,Apifox!";

// 使用 CryptoJS 进行 Base64 编码
const wordArray = CryptoJS.enc.Utf8.parse(message);
const base64Encoded = CryptoJS.enc.Base64.stringify(wordArray);

// 输出编码结果
console.log("Base64: " + base64Encoded);

Base64 解码

字符串解码:

// Base64 编码的字符串(一般从响应数据中提取)
let encodedData = {
"data": "5L2g5aW977yMQXBpZm94IQ=="
}

// 解码 Base64 编码的数据
let decodedData = CryptoJS.enc.Base64.parse(encodedData.data).toString(CryptoJS.enc.Utf8);

// 输出解码后的结果
console.log(decodedData); // "你好,Apifox!"

JSON 解码:

可通过pm.response.setBody()方法将解码后的 JSON 数据设置为响应 Body。

// 引入 CryptoJS 库
const CryptoJS = require("crypto-js");

// 从响应中获取 Base64 编码的字符串
let encodedData = pm.response.text();

// 解码 Base64 编码的数据
let decodedData = CryptoJS.enc.Base64.parse(encodedData).toString(CryptoJS.enc.Utf8);

// 解析解码后的 JSON 字符串
let jsonData = JSON.parse(decodedData);

// 将解析后的 JSON 数据设置为响应体
pm.response.setBody(jsonData);

// 输出结果
console.log(jsonData);

AES 加密

// 引入 CryptoJS 库
const CryptoJS = require("crypto-js");

// 假设这是我们要加密的`password`字段的值,从环境变量中获取
const password = pm.environment.get("password");

// 使用安全的密钥和 IV(这里为了示例简化说明,实际应用中需要保护好这些敏感信息)
const key = CryptoJS.enc.Utf8.parse('mySecretKey12345'); // 确保是 16/24/32 字节
const iv = CryptoJS.enc.Utf8.parse('myIVmyIVmyIVmyIV'); // 确保是 16 字节

// AES加密
const encrypted = CryptoJS.AES.encrypt(password, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();

// 把加密后的密码设置为一个新的变量,可以在请求体内使用
pm.environment.set("encryptedPassword", encrypted);

AES 解密

假设有一个经过 AES 加密的密文,其加密模式为 ECB,填充模式为 Pkcs7。其 AES 解密脚本示例如下:

// 引入 CryptoJS 库
const CryptoJS = require('crypto-js');

// 经过 Base64 编码的 AES 加密后的密文(一般从响应数据中提取)
const ciphertext = "Gig+YJFu4fLrrexzam/vblRV3hoT25hPZn0HoNoosHQ=";

// 解密所需密钥,确保是 16/24/32 字节(一般从环境变量中读取)
const key = CryptoJS.enc.Utf8.parse('1234567891234567');

// AES 解密
const decryptedBytes = CryptoJS.AES.decrypt(ciphertext, key, {
mode: CryptoJS.mode.ECB, // 解密模式
padding: CryptoJS.pad.Pkcs7 // 填充方式
});

// 将解密后的字节数组转换为 UTF-8 字符串
const originalText = decryptedBytes.toString(CryptoJS.enc.Utf8);

// 输出解密后的文本
console.log(originalText); // "你好,Apifox!"

RSA 加密

// 引入 jsrsasign 库
const jsrsasign = require('jsrsasign');

// 定义公钥(一般从环境变量中读取)
const publicKey = `
-----BEGIN PUBLIC KEY-----
公钥……
-----END PUBLIC KEY-----
`;

// 用公钥加密
const plaintext = "你好,Apifox!";
const pubKeyObj = jsrsasign.KEYUTIL.getKey(publicKey);

const encryptedHex = jsrsasign.KJUR.crypto.Cipher.encrypt(plaintext, pubKeyObj);
console.log("加密密文:", encryptedHex);

RSA 解密

// 引入 jsrsasign 库
const jsrsasign = require('jsrsasign');

// 定义私钥(一般从环境变量中读取)
const privateKeyPEM = `
-----BEGIN PRIVATE KEY-----
私钥……
-----END PRIVATE KEY-----
`;

// 定义密文(一般从响应数据中提取)
const ciphertext = '';

// 解密
const prvKeyObj = jsrsasign.KEYUTIL.getKey(privateKeyPEM);
const decrypted = jsrsasign.KJUR.crypto.Cipher.decrypt(ciphertext, prvKeyObj);
console.log(decrypted);

一个简单的 RSA 加密解密的完整示例参考 (注意 jsrsasign 版本为 10.3.0,其它版本语法可能会不兼容),你可以将其在 Node.js 环境下运行,并根据需要在 Apifox 中执行加密或解密的操作:

const rsa = require('jsrsasign');

// 生成 RSA 密钥对
const keypair = rsa.KEYUTIL.generateKeypair("RSA", 2048);
const publicKey = rsa.KEYUTIL.getPEM(keypair.pubKeyObj);
const privateKey = rsa.KEYUTIL.getPEM(keypair.prvKeyObj, "PKCS8PRV");

console.log("公钥:", publicKey);
console.log("私钥:", privateKey);

// 用公钥加密
const plaintext = "你好,Apifox!";
const pubKeyObj = rsa.KEYUTIL.getKey(publicKey);

const encryptedHex = rsa.KJUR.crypto.Cipher.encrypt(plaintext, pubKeyObj);
console.log("加密密钥:", encryptedHex);

// 用私钥解密
const prvKeyObj = rsa.KEYUTIL.getKey(privateKey);

const decrypted = rsa.KJUR.crypto.Cipher.decrypt(encryptedHex, prvKeyObj);
console.log("解密明文:", decrypted);

Apifox RSA 加密解密

非内置的 JS 类库

使用 fox.liveRequire 方法可以动态地引入从 npm 上发布的其他纯 JavaScript 库,以扩展 Apifox 的功能。请注意,仅支持在浏览器端运行的库,并且不支持带有 C/C++ 等语言扩展的库。如果尝试加载此类库,可能会导致运行超时或产生异常。为了最好的运行效果,请选择明确支持浏览器端运行的库,并仅引入纯 JavaScript 库。

注意
  1. 非内置库需要动态从网络下载 JS 类库,所以必须要联网,且性能有有所损耗,建议优先使用内置的 JS 库。
  2. WEB 版不支持该方式,请使用 Apifox 桌面客户端。

示例代码如下:

// 使用非内置的 JS 类库示例

// 引入单个 npm 库:md5
fox.liveRequire("md5", (md5) => {
try {
console.log(md5("message")); // => '04a410d39d39f9831217edd702d7fde0'
} catch (error) {
console.error("An error occurred during liveRequire callback", error);
throw error;
}
});

// 引入多个 npm 库:camelize,md5
fox.liveRequire(["camelize", "md5"], ([camelize, md5]) => {
try {
console.log("loaded module is ", camelize, md5);

console.log('camelize("foo-bar") is ', camelize("foo-bar")); // => 'fooBar'
console.log('md5("message") is ', md5("message")); // => '04a410d39d39f9831217edd702d7fde0'
} catch (error) {
console.error("An error occurred during liveRequire callback", error);
throw error;
}
});

// 引入多个 npm 库(带版本):camelcase,md5
fox.liveRequire(
[
{
name: "camelcase",
version: "6.2.1",
},
"md5",
],
([camelCase, md5]) => {
try {
console.log("loaded module is ", camelCase, md5);

console.log('camelCase("foo-bar") is ', camelCase("foo-bar")); // => 'fooBar'
console.log('md5("message") is ', md5("message")); // => '04a410d39d39f9831217edd702d7fde0'
} catch (error) {
console.error("An error occurred during liveRequire callback", error);
throw error;
}
}
);

SM 国密算法

具体用法可参考 gm-crypto 库,以下为示例:

fox.liveRequire("gm-crypto", (module) => {
try {
const { SM4, SM2, SM3 } = module;
const key = '0123456789abcdeffedcba9876543210'; // 32 位十六进制字符串作为密钥
const originalData = 'SM4 国标对称加密'; // 原始数据

let encryptedData, decryptedData;

// ECB 模式加密
encryptedData = SM4.encrypt(originalData, key, {
inputEncoding: 'utf8', // 输入编码为 UTF-8
outputEncoding: 'base64' // 输出编码为 Base64
});
decryptedData = SM4.decrypt(encryptedData, key, {
inputEncoding: 'base64', // 输入编码为 Base64
outputEncoding: 'utf8' // 输出编码为 UTF-8
});

// CBC 模式加密
const iv = '0123456789abcdeffedcba9876543210'; // 32 位十六进制字符串作为初始化向量
encryptedData = SM4.encrypt(originalData, key, {
iv, // 使用初始化向量
mode: SM4.constants.CBC, // 设置加密模式为 CBC
inputEncoding: 'utf8', // 输入编码为 UTF-8
outputEncoding: 'hex' // 输出编码为十六进制
});
decryptedData = SM4.decrypt(encryptedData, key, {
iv, // 使用初始化向量
mode: SM4.constants.CBC, // 设置解密模式为 CBC
inputEncoding: 'hex', // 输入编码为十六进制
outputEncoding: 'utf8' // 输出编码为 UTF-8
});

// 输出加密和解密结果
console.log('res is ', {
encryptedData,
decryptedData
});
} catch (error) {
console.error('An error occurred during liveRequire callback', error);
throw error; // 抛出错误以便调试
}
});