LoadRunner脚本无法捕获API响应体及JWT AccessToken问题
LoadRunner捕获JWT Token失败问题解决
作为LoadRunner新手,在为基于JWT Token认证的API编写脚本时,尝试捕获登录API响应体中的accessToken但多次失败,以下是相关脚本、API响应示例及解决方法:
原脚本
web_custom_request("login_2", "URL=https://reconstream-int.timestreamgroup.com/api/users/login", "Method=POST", "Resource=0", "RecContentType=application/json", "Referer=https://reconstream-int.timestreamgroup.com/login", "Snapshot=t334.inf", "Mode=HTML", "EncType=application/json", "Body={\"data\":{\"username\":\"******@gmail.com\",\"password\":\"******\"}}", LAST); web_set_user("reconstream-int.timestreamgroup.com\\******@gmail.com", "******", "reconstream-int.timestreamgroup.com"); lr_think_time(60); web_reg_save_param("data", "LB/IC={\"data\": {", "RB/IC=\"checker\": null}", LAST); lr_output_message("Response Body: %s", lr_eval_string("{data}")); /* web_reg_save_param_json( "ParamName=userId", // Specify the parameter name to store the captured value "QueryString=$.data.accessToken", // Specify the JSONPath expression to extract the value //"Ordinal=1", // Specify the occurrence of the value if there are multiple matches LAST); lr_output_message("Response Body: %s", lr_eval_string("{userId}"));*/ //web_reg_save_param("ResponseBody", "LB=\"{", "RB=\"}", "Search=Body", LAST); //lr_output_message("Response Body: %s", lr_eval_string("{ResponseBody}")); //web_reg_save_param("ResponseBody", "LB=\"{", "RB=\"}", "Search=Body", LAST); /*web_set_max_html_param_len("2560"); web_reg_save_param( "ParamName=accessToken", "LB=\"accessToken\": \"", "RB=\"", "Ord=1", "Search=Body", LAST );*/ /*web_reg_save_param_regexp( "ParamName=accessToken", "RegExp:\"accessToken\": \"(.*?)\"", SEARCH_FILTERS, "Scope=Body", LAST );*/ //web_reg_save_param("accessToken", "LB=\"accessToken\": \"", "RB=\"", "Search=Body", LAST); //web_set_user("******@gmail.com", "******", "reconstream-int.timestreamgroup.com"); //web_set_user("reconstream-int.timestreamgroup.com\\******@gmail.com", lr_decrypt("4FF8D21991C9E969CD1CAD5F16400D66"),"reconstream-int.timestreamgroup.com"); web_add_cookie("JSESSIONID={JSESSIONID}; DOMAIN=reconstream-int.timestreamgroup.com"); //web_reg_save_param_ex("ParamName=accessToken", "LB=\"accessToken\":\"", "RB=\"", LAST); //web_reg_save_param("accessTokenParam", "LB=\"accessToken\":\"", "RB=\"","Search=Body" ,"Ord=All", "NotFound=WARNING", LAST); //lr_output_message("accessToken: %s", lr_eval_string("{ResponseBody}")); // Print the captured response body if (strlen(lr_eval_string("{ResponseBody}")) > 0) { lr_output_message("Response Body: %s", lr_eval_string("{ResponseBody}")); } else { lr_output_message("Response Body not found"); } web_add_header("Authorization", "Bearer {accessToken}"); //web_add_header("Authorization", lr_eval_string("Bearer %s", lr_eval_string("{ParamName}"))); //web_add_header("Austhorization", lr_eval_string("Bearer %s", accessToken)); web_url("users", "URL=https://reconstream-int.timestreamgroup.com/api/roles/users", "Resource=0", "RecContentType=application/json", "Referer=https://reconstream-int.timestreamgroup.com/login", "Snapshot=t335.inf", "Mode=HTML", LAST);
API响应示例
{ "data": { "userId": 78, "username": "******@gmail.com", "firstName": "Mudassar ", "middleName": "Middle", "lastName": "Munir", "empCode": "mm", "mobileNo": "+923477******", "officePhone": "+03477******", "officePhoneExt": "extensions", "userLoginTypeId": 0, "newOrResetPassword": null, "userPreferences": [ { "prefKeys": "dateFormat", "prefValues": "DD-MM-YYYY" }, { "prefKeys": "timeFormat", "prefValues": "HH:mm:ss" }, { "prefKeys": "dateTimeFormat", "prefValues": "DD-MM-YYYY HH:mm:ss" } ], "lastFailureLogin": "2023-05-25T14:25:09.488+00:00", "lastLogin": "2023-05-29T07:17:22.339+00:00", "accessToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjaC5tdWRhc3Nhci5tdW5pckBnbWFpbC5jb20iLCJpYXQiOjE2ODUzNDUwMDQsImV4cCI6MTY4NTM0NTMwNCwidXNlclByaW5jaXBhbCI6eyJ1c2VySWQiOjc4LCJ1c2VybmFtZSI6ImNoLm11ZGFzc2FyLm11bmlyQGdtYWlsLmNvbSIsImZpcnN0TmFtZSI6Ik11ZGFzc2FyICIsIm1pZGRsZU5hbWUiOiJNaWRkbGUiLCJsYXN0TmFtZSI6Ik11bmlyIiwiZW1wQ29kZSI6Im1tIiwibW9iaWxlTm8iOiIrOTIzNDc3MjI0NTk1Iiwib2ZmaWNlUGhvbmUiOm51bGwsIm9mZmljZVBob25lRXh0IjpudWxsLCJ1c2VyTG9naW5UeXBlSWQiOjAsIm5ld09yUmVzZXRQYXNzd29yZCI6bnVsbCwidXNlclByZWZlcmVuY2VzIjpudWxsLCJsYXN0RmFpbHVyZUxvZ2luIjoxNjg1MDI0NzA5NDg4LCJsYXN0TG9naW4iOjE2ODUzNDUwMDQwMjUsImFjY2Vzc1Rva2VuIjpudWxsLCJyZWZyZXNoVG9rZW4iOm51bGwsImJyYW5jaE5hbWUiOm51bGwsImNoZWNrZXIiOm51bGx9fQ.d-jh1Kjy-IcZ_DwzmZna1fMzBYatbF5IupYiNNOQKop7NvwAgLPeI-B_-3jPTWV4eMUFKtubWJUf-Gwlmfxv9w", "refreshToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjaC5tdWRhc3Nhci5tdW5pckBnbWFpbC5jb20iLCJpYXQiOjE2ODUzNDUwMDQsImV4cCI6MTY4NTM0OTAwNCwidXNlclByaW5jaXBhbCI6eyJ1c2VySWQiOjc4LCJ1c2VybmFtZSI6ImNoLm11ZGFzc2FyLm11bmlyQGdtYWlsLmNvbSIsImZpcnN0TmFtZSI6bnVsbCwibWlkZGxlTmFtZSI6bnVsbCwibGFzdE5hbWUiOm51bGwsImVtcENvZGUiOiIiLCJtb2JpbGVObyI6IiIsIm9mZmljZVBob25lIjpudWxsLCJvZmZpY2VQaG9uZUV4dCI6bnVsbCwidXNlckxvZ2luVHlwZUlkIjpudWxsLCJuZXdPclJlc2V0UGFzc3dvcmQiOm51bGwsInVzZXJQcmVmZXJlbmNlcyI6bnVsbCwibGFzdEZhaWx1cmVMb2dpbiI6bnVsbCwibGFzdExvZ2luIjpudWxsLCJhY2Nlc3NUb2tlbiI6IiIsInJlZnJlc2hUb2tlbiI6bnVsbCwicmVmcmVzaFRva2VuVmFsaWQiOnRydWUsImJyYW5jaE5hbWUiOm51bGwsImNoZWNrZXIiOm51bGx9fQ.k4FtG20IaaYRo4uUtcgsnD1BeavFmJdMhuROHWzD_tBWSJq0n7c-jo-JyPZYdNjylkGa_WZVhN1QGuUNy0TT2g", "branchName": null, "checker": null }, "message": { "status": "200", "description": "SUCCESS" } }
核心问题与解决方法
1. 关联函数放置位置错误
LoadRunner中所有web_reg_*开头的注册型函数,必须放在对应的请求之前,才能在请求执行时捕获响应数据。原脚本中所有关联函数都写在了login_2请求之后,这是捕获失败的主要原因。
2. 推荐使用JSON专用关联函数
针对JSON格式的响应,使用web_reg_save_param_json比普通web_reg_save_param更精准,无需处理复杂的边界字符。
修正后的完整脚本
// 先注册JSON关联,提取accessToken,必须放在login请求之前 web_reg_save_param_json( "ParamName=accessToken", "QueryString=$.data.accessToken", "NotFound=ERROR", LAST); // 执行登录请求 web_custom_request("login_2", "URL=https://reconstream-int.timestreamgroup.com/api/users/login", "Method=POST", "Resource=0", "RecContentType=application/json", "Referer=https://reconstream-int.timestreamgroup.com/login", "Snapshot=t334.inf", "Mode=HTML", "EncType=application/json", "Body={\"data\":{\"username\":\"******@gmail.com\",\"password\":\"******\"}}", LAST); // 输出捕获到的accessToken,必须在请求之后执行 lr_output_message("捕获到的accessToken: %s", lr_eval_string("{accessToken}")); lr_think_time(60); // 添加JWT认证头,注意参数引用正确 web_add_header("Authorization", lr_eval_string("Bearer {accessToken}")); // 执行需要认证的后续请求 web_url("users", "URL=https://reconstream-int.timestreamgroup.com/api/roles/users", "Resource=0", "RecContentType=application/json", "Referer=https://reconstream-int.timestreamgroup.com/login", "Snapshot=t335.inf", "Mode=HTML", LAST);
额外注意事项
- 若API不需要Basic Auth认证,可删除
web_set_user,避免干扰JWT认证流程。 - 若响应体较大,可通过
web_set_max_html_param_len调整参数存储长度,例如设置为web_set_max_html_param_len("8192");。 - 若登录接口返回的JSESSIONID需要携带,需通过
web_reg_save_param在登录请求前注册捕获该参数,再通过web_add_cookie添加。
内容的提问来源于stack exchange,提问作者mudassar munir
相关产品推荐
相关产品推荐

