如何在Gatling中从Cookie保存XSRF Token并在后续请求头传递
解决方案:在Gatling中动态提取并复用XSRF-TOKEN
我来帮你调整代码,实现从请求8的响应Cookie中提取XSRF-TOKEN并在后续请求中复用的功能,确保每个负载测试用户会话都使用独立的令牌,完全适配并发测试场景:
关键修改要点
- 移除硬编码令牌:删掉
headers_8和headers_11中固定的X-XSRF-TOKEN值,改用动态提取的方式。 - 绑定提取逻辑到请求:在请求8的执行逻辑中,用
check()API直接从响应Cookie提取令牌并保存为会话变量,确保令牌来自当前用户的请求响应。 - 全局复用会话变量:所有需要
X-XSRF-TOKEN的请求头,统一引用提取到的会话变量,无需重复提取(除非后续请求更新了令牌)。
修改后的完整代码
import scala.concurrent.duration._ import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.util.Random class addvehicle extends Simulation { object randomIntegerGenerator { def randomInteger(range: Int) = scala.util.Random.nextInt(range).toString } val feeder = Array( Map( "Authorization" -> "Bearer XXXX" ), Map( "Authorization" -> "Bearer YYYY" ) ).random val httpProtocol = http .baseUrl("https://192.168.165.176:30479") .inferHtmlResources() .acceptHeader("application/json, text/plain, */*") .acceptEncodingHeader("gzip, deflate") .acceptLanguageHeader("IR") .userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0") // 移除硬编码的X-XSRF-TOKEN,改为动态注入 val headers_8 = Map.empty[String, String] val headers_9 = Map( "Content-Type" -> "application/json", "Origin" -> "https://192.168.165.176:30479" ) val headers_10 = Map( "Content-Type" -> "application/json", "Origin" -> "https://192.168.165.176:30479" ) val headers_11 = Map.empty[String, String] val req = """{"entryDate":"2020-10-03","vehicleVersion":"vehicleVersionValue"}""" var randomSession = Iterator.continually( Map( "randsession" -> ( req .replace("vehicleVersionValue", randomIntegerGenerator.randomInteger(10)) ) ) ) val scn = scenario("addvehicle") .feed(feeder) .feed(randomSession) .pause(1) .exec( http("request_8") .get("/find/usable?category=Vehicle") .header("Authorization","${Authorization}") .headers(headers_8) // 从响应Cookie提取XSRF-TOKEN,保存为会话变量xsrfToken .check(cookie("XSRF-TOKEN").saveAs("xsrfToken")) ) .pause(1) .exec( http("request_9") .post("/api/universal/search") .header("Authorization","${Authorization}") // 引用会话中的xsrfToken变量 .header("X-XSRF-TOKEN","${xsrfToken}") .headers(headers_9) .body(ElFileBody("C:/Users/test/Downloads/Gatling/user-files/resources/addvehicle/0009_request.json")) ) .pause(1) .exec( http("request_10") .post("/api/vehicle/create") .header("Authorization","${Authorization}") // 复用同一个xsrfToken变量 .header("X-XSRF-TOKEN","${xsrfToken}") .headers(headers_10) .body(StringBody("""${randsession}""")) .resources( http("request_11") .get("/api/bank/find") .header("Authorization","${Authorization}") .header("X-XSRF-TOKEN","${xsrfToken}") .headers(headers_11), http("request_12") .get("/api/vehicle/find?page=0&size=6&sort=createdDate,DESC") .header("Authorization","${Authorization}") .header("X-XSRF-TOKEN","${xsrfToken}") .headers(headers_11) ) ) setUp(scn.inject(atOnceUsers(5))).protocols(httpProtocol) }
额外说明
- 会话隔离性:每个负载测试用户的会话都会独立提取自己的
XSRF-TOKEN,不会出现令牌冲突的问题,完全支持高并发测试。 - 校验与提取一体:
check()API不仅能提取数据,还会自动验证响应中是否存在目标Cookie,如果缺失会标记请求失败,帮你快速定位问题。 - 令牌更新处理:如果后续某个请求返回了新的
XSRF-TOKEN,只需在该请求后再次调用check(cookie("XSRF-TOKEN").saveAs("xsrfToken")),就能覆盖原有变量继续使用。
内容的提问来源于stack exchange,提问作者Amir Soleimani Borujerdi




