在利用JMeter進行接口測試或者性能測試的時候脏嚷,我們需要處理一些復雜的請求赁炎,比如對接口請求參數(shù)進行簽名,加密意系,響應數(shù)據(jù)的驗簽及解密泥耀,以及接口公共參數(shù)的處理,此時就需要利用BeanShell腳本了蛔添,關于BeanShell的使用小伙伴們可以查看網(wǎng)上相關文章痰催。今天主要和大家分享下接口簽名兜辞,驗簽,加解密夸溶,以及處理公共參數(shù)的例子逸吵,希望能幫助到小伙伴們。
一缝裁,思路
-
約定:約定接口有統(tǒng)一的請求及響應格式扫皱,如:
請求協(xié)議公共部分
參數(shù) | 類型 | 是否必選 | 描述 |
---|---|---|---|
appKey | String | 是 | 應用key |
nonce | String | 是 | 32位UUID隨機字串,格式如:296f6fdd570244d98b6046ec135a5b8a |
sign | String | 是 | 簽名 |
timestamp | Long | 是 | 請求時間戳捷绑, |
transactionSn | String | 是 | 交易流水號 |
parameter | Object | 否 | 請求的業(yè)務對象 |
響應協(xié)議公共部分
參數(shù) | 類型 | 描述 |
---|---|---|
code | String | 返回碼 |
message | String | 返回消息韩脑,如錯誤信息 |
timestamp | String | 響應時間 |
transactionSn | String | 交易流水號 |
sign | String | 簽名 |
data | Object | 返回的業(yè)務對象 |
基于此約定,我們才能進一步統(tǒng)一處理粹污。
- 引入外部簽名及加解密工具包
- JMeter的HTTP請求->請求參數(shù)中只填寫業(yè)務對象(parameter)
- 利用前置處理器(BeanShell PreProcessor),組裝公共請求對象->對業(yè)務參數(shù)對象進行加密->簽名
- 利用后置處理器(BeanShell PostProcessor)對響應報文進行驗簽->解密段多。
二,實現(xiàn)
整體效果如下圖:
關于如何建立測試計劃壮吩,線程組就不用一一描述了进苍,這里只關注核心功能實現(xiàn)。
-
HTTP請求參數(shù)(parameter)部分鸭叙,如:
{ "idCardNo":"511622198312241918", "name":"Leo" }
-
接口調(diào)用前置處理器-簽名/加密(BeanShell PreProcessor),BeanShell代碼如下:
//引入依賴 import com.javacoo.service.base.security.util.SignUtil; import com.javacoo.service.base.security.util.SecurityUtil; import com.javacoo.service.base.utils.WebUtil; import com.javacoo.service.base.utils.FastJsonUtil; import com.javacoo.service.base.BaseRequest; import java.util.Calendar; import java.util.Map; import org.apache.jmeter.config.Arguments; //開始處理 log.info("接口調(diào)用前置處理器-簽名/加密相關處理"); Arguments args = sampler.getArguments(); //獲取請求參數(shù) String body = args.getArgument(0).getValue(); log.info("業(yè)務參數(shù):{}",body); //獲取簽名所需參數(shù) String appKey = "${appKey}"; String secretkey = "${secretkey}"; String nonce = WebUtil.genTransSn(); String transactionSn = WebUtil.genTransSn(); Long timestamp = Calendar.getInstance().getTimeInMillis(); //加密 Map bodyMap = FastJsonUtil.stringToCollect(body); log.info("params:{}",bodyMap); for(Map.Entry entry : bodyMap.entrySet()){ entry.setValue(SecurityUtil.encryptDes(entry.getValue(),secretkey)); } body = FastJsonUtil.toJSONString(bodyMap); log.info("加密后業(yè)務參數(shù):{}",body); //簽名 String sign = SignUtil.clientSign(body,nonce,timestamp.toString(),secretkey); log.info("sign:{}",sign); //組裝接口請求對象 BaseRequest baseRequest = new BaseRequest(); baseRequest.setAppKey(appKey); baseRequest.setNonce(nonce); baseRequest.setTimestamp(timestamp); baseRequest.setTransactionSn(transactionSn); baseRequest.setSign(sign); baseRequest.setParameter(FastJsonUtil.toBean(body)); //轉(zhuǎn)換為JSON字符串 String reqBody = FastJsonUtil.toJSONString(baseRequest); log.info("reqBody:{}",reqBody); //重置參數(shù)值 args.getArgument(0).setValue(reqBody);
-
接口調(diào)用后置處理程序-驗證簽名/解密(BeanShell PostProcessor),BeanShell代碼如下:
//引入依賴 import com.javacoo.service.base.security.util.SignUtil; import com.javacoo.service.base.BaseResponse; import com.javacoo.service.base.utils.FastJsonUtil; import org.apache.commons.lang3.StringUtils; //開始處理 log.info("接口調(diào)用后置處理器-驗證簽名"); String responseData = prev.getResponseDataAsString(); log.info("返回數(shù)據(jù):{}",responseData); BaseResponse baseResponse = FastJsonUtil.toBean(responseData, BaseResponse.class); if(StringUtils.isBlank(baseResponse.getSign()) || baseResponse.getData().get() == null){ return; } //轉(zhuǎn)換 String s = FastJsonUtil.toJSONString(baseResponse.getData().get()); log.info("請求返回業(yè)務json:{}",s); log.info("請求返回簽名:{}",baseResponse.getSign()); String secretkey = "${secretkey}"; //驗證簽名 if (SignUtil.cloudVerifySign(baseResponse.getSign(), s,baseResponse.getTransactionSn(),baseResponse.getTimestamp().toString(), secretkey)) { log.info("返回數(shù)據(jù)合法"); } else { log.info("返回數(shù)據(jù)被篡改"); } //解密,TODO
三觉啊,注意事項及問題
- JMeter不支持java1.5以后的語法,不支持泛型沈贝,如要使用則需要封裝成JAR包柄延。
一些信息
路漫漫其修遠兮,吾將上下而求索
碼云:https://gitee.com/javacoo
QQ群:164863067
作者/微信:javacoo
郵箱:xihuady@126.com