apifox调用jar步伐

打印 上一主题 下一主题

主题 776|帖子 776|积分 2328

背景:测试接口要用到署名,以是想通过apifox直接设置署名干系字段
解决方案:开始是预备些javascript脚本,但是一直存在依赖的方法找不到问题,后面知道可以调用java步伐,简直方便多了

一、写java步伐,并打出可执行的jar包

我是现有的springboot步伐上修改的,
1、先写天生署名的方法工具方法

  1. import cn.hutool.core.util.StrUtil;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.nio.charset.StandardCharsets;
  7. import java.nio.file.Files;
  8. import java.security.KeyFactory;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.Signature;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14. import java.util.*;
  15. public class RSAUtil {
  16.     private static final ObjectMapper objectMapper = new ObjectMapper();
  17.     private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
  18.     /**
  19.      * 使用私钥对数据进行签名
  20.      */
  21.     public static String sign(String data, PrivateKey privateKey) throws Exception {
  22.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
  23.         signature.initSign(privateKey);
  24.         signature.update(data.getBytes(StandardCharsets.UTF_8));
  25.         byte[] signBytes = signature.sign();
  26.         return Base64.getEncoder().encodeToString(signBytes);
  27.     }
  28.     /**
  29.      * 从Base64编码字符串加载私钥
  30.      */
  31.     public static PrivateKey loadPrivateKey(String base64PrivateKey) throws Exception {
  32.         byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
  33.         PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
  34.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  35.         return keyFactory.generatePrivate(spec);
  36.     }
  37.     /**
  38.      * 从文件加载私钥
  39.      */
  40.     public static PrivateKey loadPrivateKeyFromFile(String filePath) throws Exception {
  41.         System.getProperty("user.dir");
  42.         byte[] keyBytes = Files.readAllBytes(new File(filePath).toPath());
  43.         PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
  44.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  45.         return keyFactory.generatePrivate(spec);
  46.     }
  47.     public static String buildDataToSign(String requestBody, long timestamp, String nonce, String sessionId) throws JsonProcessingException {
  48.         StringBuilder content = new StringBuilder();
  49.         if(StrUtil.isNotBlank(requestBody)){
  50.             content.append("body=").append(requestBody.replaceAll("\\s+", "").trim()).append("&");
  51.         }
  52.         content.append("timestamp=").append(timestamp).append("&");
  53.         content.append("nonce=").append(nonce).append("&");
  54.         if(StrUtil.isNotBlank(sessionId)){
  55.             content.append("sessionId=").append(sessionId).append("&");
  56.         }
  57.         return content.toString().substring(0, content.length() - 1);
  58.     }
  59.     public static String buildDataToSignForSort(String requestBody, long timestamp, String nonce, String sessionId) throws JsonProcessingException {
  60.         // 将请求体转换为Map
  61.         Map<String, Object> params = new LinkedHashMap();
  62.         if(StrUtil.isNotBlank(requestBody)){
  63.             params = objectMapper.readValue(requestBody.replaceAll("\\s+", "").trim(), LinkedHashMap.class);
  64.         }
  65.         params.put("timestamp", timestamp);
  66.         params.put("nonce", nonce);
  67.         if(StrUtil.isNotBlank(sessionId)){
  68.             params.put("sessionId", sessionId);
  69.         }
  70.         SortedMap<String, Object> sortedParams = new TreeMap<>(params);
  71.         StringBuilder content = new StringBuilder();
  72.         for (String key : sortedParams.keySet()) {
  73.             if ("sign".equals(key)) continue; // 排除签名本身
  74.             if (sortedParams.get(key) != null) { // 忽略值为null的字段
  75.                 content.append(key).append("=").append(sortedParams.get(key)).append("&");
  76.             }
  77.         }
  78.         String str= content.toString().substring(0, content.length() - 1); // 移除最后一个 &
  79.         return str;
  80.     }
  81. }
复制代码
2、写main方法,根据参数天生署名

  1. @SpringBootApplication
  2. public class TestApplication {
  3.         public static void main(String[] args) {
  4.         String rsaPrivateKey = "yourprivatekey";
  5.         String requestBody = args[0];
  6.         Long timestamp = StrUtil.isBlank( args[1]) ? null : Long.parseLong( args[1]);
  7.         String nonce = args[2];
  8.         String sessionId = null;
  9.         if(args.length>3){
  10.             sessionId = args[3];
  11.         }
  12.         try {
  13.             // 构造待验签的数据
  14.             String dataToVerify = RSAUtil.buildDataToSign(requestBody, timestamp, nonce, sessionId);
  15.             PrivateKey privateKey = RSAUtil.loadPrivateKey(rsaPrivateKey);
  16.             String genPrivateSignStr = RSAUtil.sign(dataToVerify, privateKey);
  17.             System.out.println(genPrivateSignStr);
  18.         } catch (Exception e) {
  19.             throw new RuntimeException(e);
  20.         }
  21.     }
  22. }
复制代码
3、天生jar包:RSA.jar

可以通过下令行验证jar包是否正常,java -jar RSA .jar 参数等等

二、设置apifox

1、引入jar包

找到设置-》外部步伐,打开目次,然后把RSA.jar拷贝到这个目次下


2、设置环境变量

设置后会往这个内里设置值



3、编写前置操作的脚本

选择前置操作-》增加前置操作-》自定义脚本

  1. // 获取当前时间戳(毫秒)
  2. const timestamp = Date.now();
  3. // 生成随机数(nonce)
  4. const nonce = btoa(Math.random().toString().slice(2)).slice(0, 16);
  5. // 检查是否需要 sessionId(例如通过环境变量或请求参数获取)
  6. let sessionId = pm.variables.get('sessionId') || '';
  7. // 获取请求体内容
  8. // const requestBody = JSON.stringify(pm.request.body.raw);
  9. // const requestBodyRaw = pm.request.body.raw;
  10. let requestBodyRaw = pm.request.body.raw;
  11. // 检查 requestBodyRaw 是否为 null 或者仅包含空白字符
  12. if (!requestBodyRaw || requestBodyRaw.trim() === '') {
  13.     requestBodyRaw = ''; // 设置为空字符串
  14. }
  15. const requestBody = typeof requestBodyRaw === 'string' ? requestBodyRaw.trim() : JSON.stringify(requestBodyRaw);
  16. // var requestBodyRaw2 = requestBodyRaw;
  17. // // 确保 requestBody 是原始的 JSON 字符串,并且清理多余空白字符
  18. // if (typeof requestBodyRaw === 'string') {
  19. //     // 去除多余的空白字符(包括换行符和制表符)
  20. //     requestBodyRaw2 = requestBodyRaw2.trim().replace(/\s+/g, ' ');
  21.    
  22. //     // 如果 JSON 字符串中包含转义的双引号,尝试修复它们
  23. //     requestBodyRaw2 = requestBodyRaw2.replace(/\\"/g, '"');
  24. // }
  25. const urlPathArray = pm.request.url.path;
  26. // 定义你想要匹配的最后一级路径
  27. const targetLastPath = 'login';
  28. if (urlPathArray.length === 0) {
  29.     console.log("URL 路径为空");
  30. } else {
  31.     // 获取最后一级路径
  32.     const lastPath = urlPathArray[urlPathArray.length - 1];
  33.     if (lastPath === targetLastPath) {
  34.         sessionId  = ''; // 设置为空字符串
  35.     }
  36. }
  37. const signatureBase64 = pm.execute("RSA.jar", [requestBody, timestamp, nonce, sessionId]);
  38. // 将签名设置到环境变量中,以便在后续请求中使用
  39. pm.environment.set("X-Signature", signatureBase64);
  40. pm.environment.set("X-Timestamp", timestamp);
  41. pm.environment.set("X-Nonce", nonce);
  42. // 打印签名结果,用于调试
  43. console.log("Signature: ", signatureBase64);
复制代码

4、接口设置读取环境变量



5、点击接口发送即可以验证测试

可以在控制台看日记

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表