性能测试处理动态令牌(Token)和会话(Session)是保证脚本能够真实模拟多用户并发操作的重要技术,主要通过在LoadRunner中实现关联(Correlation)来完成。关联是从服务器响应中捕获动态变化的值,作为变量供后续请求使用。
特征:
典型形式:JSESSIONID, PHPSESSID, session_id,csrf_token, access_token, viewstate,订单号、证实码、时间戳、流程实例ID
主要目的:在服务器端标识并跟踪一次用户会话状态。 防止重复提交或进行接口访问授权。标识唯一的业务实体或包含上下文信息。
变化规律:每次新登录或会话开始时,服务器都会生成一个新值。 一般随页面加载或表单请求生成,有一定有效期。根据业务规则(如递增、随机)生成。
存放位置:一般通过 Set-Cookie 在HTTP头部下发,或嵌入在响应体中。一般以隐藏字段(如<input type="hidden">)或JSON字段的形式出现在响应体中。一般出现在JSON响应、HTML正文或重定向URL中。
使用方式:后续请求自动通过Cookie携带,或需手动提取并放入请求头/体。必须手动提取,并在下一次表单提交或请求头(如Authorization: Bearer)中回传。需要在后续请求的特定参数中回传。
未处理的后果:所有虚拟用户(Vuser)都使用录制时固定的Session ID,导致请求被服务器识别为同一会话,可能触发登录失败或数据混乱。提交过期的或无效的令牌,服务器会返回“令牌无效”、“重复提交”等错误。 导致业务流程中断,如用已使用的订单号再次提交。
实现关联的步骤和函数
实现关联,是使用注册型关联函数(如 web_reg_save_param_ex),这类函数需要在触发服务器响应的请求(如 web_url)之前声明,工作原理是钩住接下来的响应,并根据设定的左右边界(LB/RB)提取文本保存为参数。
手动关联的流程如下:
录制并回放,确定问题:录制包含登录或获取Token的脚本,回放时如果失败,查看日志,如果发现服务器返回的动态值和录制时不同,即可确定。
定位并捕获动态值:
定位响应:在Tree View中,找到失败前一步的服务器响应(如登录请求)。
确定边界:在响应内容中找到动态值,分析其左侧(LB)和右侧(RB)唯一且固定不变的文本作为边界。
插入函数:在生成该响应的请求函数之前,插入关联函数,设置参数名和边界。
替换参数:将脚本中原先硬编码(Hard-Coded)的动态值替换成 {参数名}。
调试:重新回放脚本,启用扩展日志(Extended log)查看参数是不是被正确捕获和替换。
实战案例分析
下面通过两个典型情形演示怎样操作。
案例一:处理登录会话 (Session ID)
以经典的WebTours登录为例。登录前,服务器会在首页响应中分配一个动态的userSession值。
捕获:在访问首页的请求web_url("WebTours")前,插入关联函数。
替换:在后续登录请求web_submit_data("login.pl")中,将"Value=108993.054434994..."替换为"Value={UserSession}"。
代码示例:
// 1. 在请求前注册关联,捕获动态的userSession web_reg_save_param_ex( "ParamName=UserSession", "LB=name=\"userSession\" value=\"", // 左边界 "RB=\">", // 右边界 "Search=Body", LAST); // 2. 执行请求,响应中的userSession会被捕获到`UserSession`参数 web_url("WebTours", "URL=http://127.0.0.1:1080/WebTours/", ...); // 3. 在后续的登录请求中,使用捕获到的参数 web_submit_data("login.pl", ITEMDATA, "Name=userSession", "Value={UserSession}", ENDITEM, // 动态值替换在此 "Name=username", "Value=test", ENDITEM, "Name=password", "Value=1", ENDITEM, LAST);文章来源:卓码软件测评
精彩推荐:点击蓝字即可
▲软件负载测试▲API自动化测试▲软件测试▲第三方软件测试▲软件性能测试▲软件测试机构
案例二:处理防跨站请求伪造令牌 (CSRF Token)
在提交表单前,常需从页面获取一个CSRF令牌。
捕获:在加载表单页面的请求前,插入关联函数捕获csrf_token。
替换:在提交表单的请求中,将此令牌作为一项数据提交。
代码示例:
// 1. 在访问表单页面前注册关联,捕获CSRF令牌 web_reg_save_param_ex( "ParamName=CsrfToken", "LB=<input type=\"hidden\" name=\"csrf_token\" value=\"", "RB=\"", "Search=Body", LAST); web_url("form_page.html", ...); // 2. 在提交表单时使用捕获到的令牌 web_submit_data("submit_action.php", ITEMDATA, "Name=csrf_token", "Value={CsrfToken}", ENDITEM, // 动态令牌替换 "Name=data", "Value=example", ENDITEM, LAST);技巧调试
处理多个相同值:当响应中有多个结构相同的动态值(如商品列表ID)时,在关联函数中设置 "Ord=All",捕获的所有值会存储为数组,可通过 {ParamName_1}、{ParamName_2} 等方式引用。
JSON响应处理:对于JSON格式的响应(如REST API返回的 access_token),使用 web_reg_save_param_json 函数配合JSON Path途径来提取更为准确和方便。
调试和排查:必须在 Runtime Settings -> Log 中启用 Extended log 并勾选 Parameter substitution。回放时通过查看日志,可以清晰看到参数是不是被正确捕获和替换,这是定位关联问题最直接的方法。
自动关联的辅助:LoadRunner提供扫描关联(Scan for Correlation)功能,可自动比对两次录制脚本的差别,提示可能的关联点。但不能完全依赖自动结果,需人工核对边界和必要,因为自动关联可能遗漏或误关联。