Jmeter学习和一个关于jmeter获取X-XSRF-TOKEN时的坑

Jmeter学习和一个关于jmeter获取X-XSRF-TOKEN时的坑

现在想对一个接口做性能测试,需要测试它多个线程并发下的调用

1.新建测试计划和线程组

2.新建http接口

一个完整的http接口包含请求头和请求,这里就需要两个组件:HTTP request、HTTP Header Manager。

2-1 HTTP request

需要填写以下内容。

image-20230119162208426

2-2 HTTP Header Manager

这里需要关注的是X-XSRF-TOKEN,它是动态的。

如果是第一次发请求,请求参数不带X-XSRF-TOKEN,响应头就会返回一个X-XSRF-TOKEN。

第二次请求就必须在请求头中带上上次请求返回的X-XSRF-TOKEN,否则就会返回403,并报错如下。

Invalid CSRF Token 'null' was found on the request parameter 'csrf' or header 'x-xsrf-token'

那么这里的难点就在于每次都需要从上一次请求的响应头中获取返回的X-XSRF-TOKEN,并设置到下一次请求的请求头中

image-20230119162321370

响应头中要提取的数据长这样:

image-20230129103948223

3.提取response Header返回的动态变量

这里介绍了正则表达式提取和边界表达式提取两种方法,任选一种即可。

遇到的一个坑,暂时不知道为什么:

在本地启动项目时,即项目地址的IP是localhost时,正则提取不到,必须用边界表达式提取;

在云服务器上启动时,即项目地址的IP是云服务器的IP时,边界表达式提取不到,必须用正则提取。

3-1 Regular Expression Extractor

通过正则表达式提取和引用X-XSRF-TOKEN

image-20230129103843442

提取之后在下一个请求的请求头中这样引用

image-20230129104054024

3-2 Boundary Extractor

通过边界表达式提取和引用X-XSRF-TOKEN

image-20230129104358077

提取之后在下一个请求的请求头中这样引用

image-20230129104430298

4.提取登录后response Data返回的token

要提取的token长这样

image-20230129112602450

4-1 JSON Extractor

image-20230129112426309

5.设置一个接口的多次调用

5-1 添加事务控制器-Transaction Controller

image-20230129113531808

5-2 添加循环控制器-Loop Controller

放在事务控制器里面

image-20230129113511558

5-3 添加计数器-Counter

放到循环控制器里面

image-20230129113818171

5-4 添加BeanShell取样器-BeanShell Sampler

放到循环控制器里面

image-20230129113940393

5-5 添加http接口

放到循环控制器里面

接口里面包含HTTP request和HTTP Header Manager,除此之外,要想对接口进行参数化,即多次调用接口每次传入不同的参数,还需要添加CSV数据文件配置

5-5-1 HTTP request

5-5-2 HTTP Header Manager

5-5-3 CSV Data Set Config

放到接口里面

image-20230129172400604

6.添加结果树查看运行结果

放在线程组下面,就显示线程组的运行结果。

image-20230129175050460

7.一个关于jmeter获取X-XSRF-TOKEN时的坑

​ 一次业务需求中需要对某些业务接口进行接口性能测试。都是调试通过的接口,在jmeter中录入后调用却卡在鉴权的第一步,反复报403失败。

​ 这里必须讲一下我们业务设计里调用接口的前提:X-XSRF-TOKEN和access_token双认证。

X-XSRF-TOKEN:在每一次请求时生成一个XSRF-TOKEN,必须在之后的每个请求中传递

access_token:在登陆成功后返回一个access_token,每一次业务接口调用都需要这个access_token

报错内容:

403 {"error":"access_denied","error_description":"Could not verify the provided CSRF token because your session was not found."}

也就是我还卡在第一步,登录接口都没调通,原因是没有携带X-XSRF-TOKEN发送请求。

尝试了n次之后,大概把失败的情况分为两种:

1.未添加HTTP Cookie Manager

2.添加了HTTP Cookie Manager

7-1 未添加HTTP Cookie Manager

(1)第一个请求:请求失败报403。没有携带X-XSRF-TOKEN时发送请求,响应中会自动返回一个X-XSRF-TOKEN,图略,下面有

(2)第二个请求:请求失败报403。请求头中携带从第一个请求响应头中提取到的X-XSRF-TOKEN

(3)第三个请求:请求失败报403。请求头中携带从第二个请求响应头中提取到的X-XSRF-TOKEN

所以得出结论:这里必须添加HTTP Cookie Manager。

如果不添加HTTP Cookie Manager,请求一个也成功不了,虽然我每次请求都带上了上一次请求返回的X-XSRF-TOKEN,请求仍然会失败报错。

7-2 添加了HTTP Cookie Manager

(1)第一个请求:请求失败报403。没有携带X-XSRF-TOKEN时发送请求,响应中会自动返回一个X-XSRF-TOKEN,如图所示

image-20230130155455370

image-20230130154718437

(2)第二个请求:请求成功报200。请求头中携带从第一个请求响应头中提取到的X-XSRF-TOKEN,但响应Header中本来应该有的【Set-Cookie: XSRF-TOKEN=…】却消失了

image-20230130155204313

(3)第三个请求:请求失败报403。由于第二个请求返回的响应Header中没有XSRF-TOKEN,所以没有携带X-XSRF-TOKEN时发送请求,错误同第一个请求

image-20230130155610737

image-20230130155558297

7-3 原因分析

这个问题困扰了我非常非常久,并且也没有在网上搜索到同类问题,使用apifox、postman等工具都不会出现这种情况,只有jmeter反复失败:

  • 尝试不添加HTTP Cookie Manager,一次请求也成功不了;

  • 一旦添加HTTP Cookie Manager,第二次请求能够成功,但从第二次请求起,返回的响应头中的【Set-Cookie:XSRF-TOKEN=…】就没有了,导致后面请求全部失败,非常见鬼。

后来慢慢意识到原因可能是:【Set-Cookie:XSRF-TOKEN=…】第二次被返回过来时,它已经被交给HTTP Cookie Manager来管理了,就不在响应头中展示了。

延申发现,不仅仅是【XSRF-TOKEN】,所有响应头中的【Set-Cookie:xxx=】都只会在响应头中出现一次,第二次请求中返回【xxx】变量,jmeter就会将其交给HTTP Cookie Manager来管理,它也就不再显示在response header中了。

注:Set-Cookie开头的响应头内容,意味着把Set-Cookie中的键和值设置到cookie中

为了验证这个猜测,连续三次调用登录接口发现:

  • 第一次调用:因为未携带X-XSRF-TOKEN,登录失败,返回的响应头中【Set-Cookie:XSRF-TOKEN=…】
  • 第二次调用:携带X-XSRF-TOKEN,登录成功,返回的响应头中【Set-Cookie:XSRF-TOKEN=…】消失了,但多出【Set-Cookie:access_token=…】、【Set-Cookie:session_token=…】
  • 第三次调用:登录失败,返回的响应头中没有任何【Set-Cookie:…】数据

出现过一次的【Set-Cookie:xxx=…】没有再出现第二次。

这个尝试不能完全证明我的猜测,但也没有证伪。

然后我开始进一步验证我所需要的结论:接口每次调用其实都返回了对应的【Set-Cookie:XSRF-TOKEN=…】,只是由于被jmeter的HTTP Cookie Manager管理了,所以第二次返回的XSRF-TOKEN不再存在于响应头中,而是存在于cookie中。

7-4 解决方案

那么只有第一次请求后需要用正则表达式获取响应头中的XSRF-TOKEN,第二次及之后就需要从cookie中去取它的值

注:jmeter中从cookie中获取变量值语法:${COOKIE_变量名}

  • 第一次请求:因为未携带X-XSRF-TOKEN,登录失败,返回的响应头中【Set-Cookie:XSRF-TOKEN=…】,图略

  • 第二次请求:从边界表达式提取第一次请求返回的响应头中的XSRF-TOKEN

    image-20230130164248310

    image-20230130164110297

  • 第三次请求:从cookie中提取第二次请求返回的响应头中的XSRF-TOKEN(被设置到cookie中,响应头中提取不到了)

    image-20230130164629716

    image-20230130165006512

  • 第四次请求:从cookie中提取第三次请求返回的响应头中的XSRF-TOKEN(被设置到cookie中,响应头中提取不到了)

    image-20230130164711342

    image-20230130164851312

7-5 总结

所以整理之后的脚本进行合理的调整后应该长这样:

image-20230130173133227

其中的每个部件:

(1)全局HTTP Cookie管理器

image-20230130173437207

(2)全局HTTP请求头

image-20230130173714739

(3)登录前置事务管理器、边界表达式提取器

  • 登录前置事务管理器

    image-20230130173749251

  • 边界表达式提取器

    image-20230130173804687

(4)登录事务管理器、登录请求头、json提取器

  • 登录事务管理器

    image-20230130173832029

  • 登录请求头

    image-20230130173846686

  • json提取器

    image-20230130173904756

(5)业务事务管理器、业务请求头

  • 业务事务管理器

    image-20230130173924742

  • 业务请求头

    image-20230130173941402

(6)结果树

image-20230130173950898

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/65479.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 代码重试实现方式

Java 代码重试实现方式 一.方法内直接自动重试二.静态代理方式1.启动类2.接口3.实现4.静态代理5.单元测试类 三.JDK 动态代理1.代理类2.单元测试 四.CGLIB 动态代理1.动态代理类2.单元测试 五.手动 AOP1.自定义注解2.重试注解切面3.测试类4.单元测试方法 六.Spring Retry1.测试…

虚拟机centos7配置网络

虚拟机centos7配置网络 centos7克隆之后需要配置网络才能联网。 实验环境: VMware Workstation Pro 16CentOS 7系统虚拟机主机Windows 11系统 1.VMware网络模式设置为NAT模式 虚拟机–设置–网络适配器– ​​ ‍ 2.查看虚拟机 子网IP和网关IP 编辑–虚拟网…

pytorch Stream 多流处理

CUD Stream https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#c-language-extensions 中指出在kenel的调用函数中最后一个可选参数表示该核函数处在哪个流之中。 - 参数Dg用于定义整个grid的维度和尺寸,即一个grid有多少个block。为dim3类型。…

Openlayers实战:利用turf获取两个多边形的交集、差集、并集

在数据统计方面,通常会涉及到图形间的交集、并集、差集等。在Openlayers的实战中,我们显示两个多边形的交集、并集、差集的表现。通过turf的方式,可以快速的实现我们的数据处理,具体的请参考源代码。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师…

MySQL 事务原理:事务概述、隔离级别、MVCC

文章目录 一、事务1.1 事务概述1.2 事务控制语句1.3 ACID特性 二、隔离级别2.1 隔离级别的分类2.1.1 读未提交(RU)2.1.2 读已提交(RC)2.1.3 可重复读(RR)2.1.4 串行化 2.2 命令2.3 并发读异常2.3.1 脏读2.3…

Redis实战案例25-附近商铺功能

1. GEO数据结构 Redis中Geohash功能应用 添加地理坐标 求两点之间距离 搜索天安门附近10km的火车站,按升序 2. 导入店铺数据到GEO Redis中存储店铺的信息,将店铺的id和经纬度坐标存到GEO数据类型中去,其中member存id,经纬度对应…

Docker实战-操作Docker容器实战(二)

导语   上篇分享中,我们介绍了关于如何创建容器、如何启动容器、如何停止容器。这篇我们来分享一下如何操作容器。 如何进入容器 可以通过使用-d参数启动容器后会进入后台运行,用户无法查看容器中的信息,无法对容器中的信息进行操作。 这个时候如果我们需要进入容器对容器…

C语言经典小游戏之扫雷(超详解释+源码)

“少年气,是历尽千帆举重若轻的沉淀,也是乐观淡然笑对生活的豁达!” 今天我们学习一下扫雷游戏怎么用C语言来实现! 扫雷小游戏 1.游戏介绍2.游戏准备3.游戏实现3.1生成菜单3.2游戏的具体实现3.2.1初始化棋盘3.2打印棋盘3.3布置雷…

黑马头条项目学习--Day1: 环境搭建、SpringCloud微服务(注册发现、网关)

Nacos注册发现、网关 a. 项目介绍b. app登录1) 需求分析2) 表结构分析3) 手动加密(md5随机字符串)4) 用户端微服务搭建5) 功能实现6) app网关7) 网关校验jwt8) 前端集成, 配置nginx a. 项目介绍 业务说明 技术栈说明 [外链图片转存失败,源站可能有防盗…

Spring Boot多级缓存实现方案

1.背景 缓存,就是让数据更接近使用者,让访问速度加快,从而提升系统性能。工作机制大概是先从缓存中加载数据,如果没有,再从慢速设备(eg:数据库)中加载数据并同步到缓存中。 所谓多级缓存,是指在整个系统架…

SpringBoot之logback-spring.xml详细配置

《logback官网》 各种指导文件&#xff0c;有空自己去看&#xff0c;比如&#xff1a;我们需要调整的是布局&#xff0c;直接看Layouts。 pom.xml <!-- 环境配置 --><profiles><profile><id>dev</id><properties><spring.profiles.a…

前端例程20230806:彩色灯珠装饰

演示 这里页面四周的彩色灯珠是会随着页面调整自动调整位置的。 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta na…

【数据结构与算法——TypeScript】哈希表

【数据结构与算法——TypeScript】 哈希表(HashTable) 哈希表介绍和特性 哈希表是一种非常重要的数据结构&#xff0c;但是很多学习编程的人一直搞不懂哈希表到底是如何实现的。 在这一章节中&#xff0c;我门就一点点来实现一个自己的哈希表。通过实现来理解哈希表背后的原理…

2022年03月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 已知a“161”&#xff0c;b“16”&#xff0c;c“8”,执行语句da>b and a>c&#xff0c;变量d的值为是&#xff1f; A&#xff1a;0 B&#xff1a;1 C&#xff1a;True D&am…

探究使用HTTP爬虫ip后无法访问网站的原因与解决方案

在今天的文章中&#xff0c;我们要一起来解决一个常见问题&#xff1a;使用HTTP爬虫ip后无法访问网站的原因是什么&#xff0c;以及如何解决这个问题。我们将提供一些实际的例子和操作经验&#xff0c;帮助大家解决HTTP爬虫ip无法访问网站的困扰。 1、代理服务器不可用 使用HT…

【SpringBoot笔记】定时任务(cron)

定时任务就是在固定的时间执行某个程序&#xff0c;闹钟的作用。 1.在启动类上添加注解 EnableScheduling 2.创建定时任务类 在这个类里面使用表达式设置什么时候执行 cron 表达式&#xff08;也叫七子表达式&#xff09;&#xff0c;设置执行规则 package com.Lijibai.s…

面试常问:tcp的三次握手和四次挥手你了解吗?

三次握手和四次挥手是各个公司常见的考点&#xff0c;一个简单的问题&#xff0c;却能看出面试者对网络协议的掌握程度&#xff0c;对问题分析与解决能力&#xff0c;以及数据流管理理解和异常情况应对能力。所以回答好一个tcp的三次握手和四次挥手的问题对于我们的面试成功与否…

(vue)获取对象的键遍历,同时循环el-tab页展示key及内容

(vue)获取对象的键遍历&#xff0c;同时循环el-tab页展示key及内容 效果&#xff1a; 数据结构&#xff1a; "statusData": {"订购广度": [ {"id": 11, "ztName": "广", …

C++笔记之两个类的实例之间传递参数的各种方法

C笔记之两个类的实例之间传递参数的各种方法 code review! 文章目录 C笔记之两个类的实例之间传递参数的各种方法1.构造函数参数传递2.成员函数参数传递3.友元函数4.友元类5.传递指针或引用6.静态成员变量7.静态成员函数8.全局变量或命名空间9.回调函数和函数指针10.观察者模…

pg实现月累计

获取每月累计数据&#xff1a; ​​​ SELECT a.month, SUM(b.total) AS total FROM ( SELECT month, SUM(sum) AS total FROM ( SELECT to_char(date("Joinin"),YYYY-MM) AS month , COUNT(*) AS sum FROM "APP_HR_Staff_Basic_Info" GROUP BY month ) …