You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 11:39:52