如何在网络性能测试中提取 X-XSRF_TOKEN
How to extract the X-XSRF_TOKEN in a web performance test
我写了一个网络性能测试,之前运行良好。开发人员现在添加了 CSRF 令牌验证(以防止网站上的 CSRF 攻击)。此后,测试开始失败(错误、错误请求)。我深入研究它,发现服务器在登录请求时生成一个 XSRF-TOKEN,此后必须在每个请求中传递该令牌。
现在要提取令牌,我们需要解析对登录请求的响应。我们该怎么做?
我的编码测试如下所示:
WebTestRequest request4 = new WebTestRequest("https://servertest:8080/WebConsole/Account/Login");
request4.Method = "POST";
request4.Headers.Add(new WebTestRequestHeader("Accept", "application/json, text/plain, */*"));
request4.Headers.Add(new WebTestRequestHeader("Referer", "https://servertest:8080/WebConsole/index.html#/"));
StringHttpBody request4Body = new StringHttpBody();
request4Body.ContentType = "application/json;charset=utf-8";
request4Body.InsertByteOrderMark = false;
request4Body.BodyString = "{\"UserName\":\"pkdomain\\administrator\",\"Password\":\"sqa@123\"}";
request4.Body = request4Body;
yield return request4;
request4 = null;
WebTestRequest request5 = new WebTestRequest("https://servertest:8080/WebConsole/scripts/home/Pages/home-view.html");
request5.ThinkTime = 4;
request5.Headers.Add(new WebTestRequestHeader("Accept", "text/html"));
request5.Headers.Add(new WebTestRequestHeader("Referer", "https://servertest:8080/WebConsole/index.html#/"));
yield return request5;
request5 = null;
我相信 XSRF-TOKEN
是在 cookie 中返回的。假设您的情况是这样,那么 Set-Cookie
header 字段包含该值,并且必须从中提取所需的 cookie 并将其保存到上下文参数中。随后可以在任何需要的地方使用该上下文参数。
我建议你创建一个沙箱 .webtest
文件,执行以下步骤然后将其转换为编码测试并将有用的行复制到真实测试中。
更详细的步骤是:
将 Set-Cookie
header 字段的 Extract HTTP Header
提取规则添加到 returns XSRF-TOKEN
值的请求中。将提取的值保存到您选择的上下文参数中,在提取规则的属性之一中给出其名称;见下图。
在具有上述提取规则的请求之后的第一个请求中添加对以下插件的调用。它从 cookie header 字段中提取所需的字段。下图显示了设置调用的属性。 (您可以将插件更改为 PostRequest
并将其添加到与提取规则相同的请求中。)
public class ExtractCookieField : WebTestRequestPlugin
{
public string AllCookiesCP { get; set; }
public string FieldWantedCP { get; set; }
public string SavedFieldCP { get; set; }
// Expected to be called with AllCookiesCP containing text similar to:
// SomeHeader=639025785406236250; path=/; XSRF-TOKEN=somestring; secure; HttpOnly
public override void PreRequestDataBinding(object sender, PreRequestDataBindingEventArgs e)
{
string AllCookiesText = e.WebTest.Context[AllCookiesCP].ToString();
foreach (string nameValuePair in AllCookiesText.Split(';'))
{
string[] nameAndValue = nameValuePair.Split(new char[] { '=' }, 2);
if (nameAndValue[0].Trim() == FieldWantedCP)
{
string sessionTokenId = nameAndValue[1].Trim();
e.WebTest.Context[SavedFieldCP] = sessionTokenId;
e.WebTest.AddCommentToResult(string.Format("Setting {{{0}}} to '{1}'", SavedFieldCP, sessionTokenId));
return;
}
}
// Dropping out of the loop means that the field was not found.
throw new WebTestException(string.Format("Cannot extract cookie field '{0}' from '{1}'", FieldWantedCP, AllCookiesText));
}
}
XSRF-TOKEN
的值现在应该在插件调用的 SavedFieldCP
属性 中指定的上下文参数中。
此图显示了添加提取规则对话框和设置保存提取的 header 字段的上下文参数,即 CookieValues
。它还显示添加插件和设置三个属性。插件运行后,假设成功,应该将token值保存到context参数XsrfToken
中。可以通过提取规则和插件的属性面板在 .webtest
文件中修改参数值。在编码的 webb 测试中,这些值也应该清楚地视为简单的变量和字符串。
我写了一个网络性能测试,之前运行良好。开发人员现在添加了 CSRF 令牌验证(以防止网站上的 CSRF 攻击)。此后,测试开始失败(错误、错误请求)。我深入研究它,发现服务器在登录请求时生成一个 XSRF-TOKEN,此后必须在每个请求中传递该令牌。 现在要提取令牌,我们需要解析对登录请求的响应。我们该怎么做?
我的编码测试如下所示:
WebTestRequest request4 = new WebTestRequest("https://servertest:8080/WebConsole/Account/Login");
request4.Method = "POST";
request4.Headers.Add(new WebTestRequestHeader("Accept", "application/json, text/plain, */*"));
request4.Headers.Add(new WebTestRequestHeader("Referer", "https://servertest:8080/WebConsole/index.html#/"));
StringHttpBody request4Body = new StringHttpBody();
request4Body.ContentType = "application/json;charset=utf-8";
request4Body.InsertByteOrderMark = false;
request4Body.BodyString = "{\"UserName\":\"pkdomain\\administrator\",\"Password\":\"sqa@123\"}";
request4.Body = request4Body;
yield return request4;
request4 = null;
WebTestRequest request5 = new WebTestRequest("https://servertest:8080/WebConsole/scripts/home/Pages/home-view.html");
request5.ThinkTime = 4;
request5.Headers.Add(new WebTestRequestHeader("Accept", "text/html"));
request5.Headers.Add(new WebTestRequestHeader("Referer", "https://servertest:8080/WebConsole/index.html#/"));
yield return request5;
request5 = null;
我相信 XSRF-TOKEN
是在 cookie 中返回的。假设您的情况是这样,那么 Set-Cookie
header 字段包含该值,并且必须从中提取所需的 cookie 并将其保存到上下文参数中。随后可以在任何需要的地方使用该上下文参数。
我建议你创建一个沙箱 .webtest
文件,执行以下步骤然后将其转换为编码测试并将有用的行复制到真实测试中。
更详细的步骤是:
将 Set-Cookie
header 字段的 Extract HTTP Header
提取规则添加到 returns XSRF-TOKEN
值的请求中。将提取的值保存到您选择的上下文参数中,在提取规则的属性之一中给出其名称;见下图。
在具有上述提取规则的请求之后的第一个请求中添加对以下插件的调用。它从 cookie header 字段中提取所需的字段。下图显示了设置调用的属性。 (您可以将插件更改为 PostRequest
并将其添加到与提取规则相同的请求中。)
public class ExtractCookieField : WebTestRequestPlugin
{
public string AllCookiesCP { get; set; }
public string FieldWantedCP { get; set; }
public string SavedFieldCP { get; set; }
// Expected to be called with AllCookiesCP containing text similar to:
// SomeHeader=639025785406236250; path=/; XSRF-TOKEN=somestring; secure; HttpOnly
public override void PreRequestDataBinding(object sender, PreRequestDataBindingEventArgs e)
{
string AllCookiesText = e.WebTest.Context[AllCookiesCP].ToString();
foreach (string nameValuePair in AllCookiesText.Split(';'))
{
string[] nameAndValue = nameValuePair.Split(new char[] { '=' }, 2);
if (nameAndValue[0].Trim() == FieldWantedCP)
{
string sessionTokenId = nameAndValue[1].Trim();
e.WebTest.Context[SavedFieldCP] = sessionTokenId;
e.WebTest.AddCommentToResult(string.Format("Setting {{{0}}} to '{1}'", SavedFieldCP, sessionTokenId));
return;
}
}
// Dropping out of the loop means that the field was not found.
throw new WebTestException(string.Format("Cannot extract cookie field '{0}' from '{1}'", FieldWantedCP, AllCookiesText));
}
}
XSRF-TOKEN
的值现在应该在插件调用的 SavedFieldCP
属性 中指定的上下文参数中。
此图显示了添加提取规则对话框和设置保存提取的 header 字段的上下文参数,即 CookieValues
。它还显示添加插件和设置三个属性。插件运行后,假设成功,应该将token值保存到context参数XsrfToken
中。可以通过提取规则和插件的属性面板在 .webtest
文件中修改参数值。在编码的 webb 测试中,这些值也应该清楚地视为简单的变量和字符串。