news 2026/4/18 15:52:05

第三方软件评测测试实验室【Gatling模拟认证用户登录、令牌使用、自动刷新到并发会话控制】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第三方软件评测测试实验室【Gatling模拟认证用户登录、令牌使用、自动刷新到并发会话控制】

Gatling模拟需要认证的用户行为涉及从登录、令牌使用、自动刷新到并发会话控制。

认证会话

模拟登录和令牌管理

建立认证会话的第一步。

执行登录提取令牌

import io.gatling.core.Predef._ import io.gatling.http.Predef._ class AuthenticationSimulation extends Simulation { val httpProtocol = http.baseUrl("https://api.zmtests.com") // 1. 定义用户证据Feeder val credentialsFeeder = csv("data/credentials.csv").circular val loginScenario = scenario("用户登录和令牌管理") .feed(credentialsFeeder) // 2. 执行登录请求 .exec( http("用户登录") .post("/auth/login") .body(StringBody("""{"username":"${username}", "password":"${password}"}""")).asJson .check( // 3. 重点:从响应中提取令牌并存入Session jsonPath("$.access_token").saveAs("accessToken"), jsonPath("$.refresh_token").optional.saveAs("refreshToken"), jsonPath("$.expires_in").optional.saveAs("tokenExpiresIn") ) ) .exec(session => { // 4. 记录登录成功时间,用于计算令牌过期 println(s"用户 ${session("username").as[String]} 登录成功,令牌: ${session("accessToken").as[String].take(10)}...") session.set("loginTime", System.currentTimeMillis() / 1000) }) .pause(1) }

重点:使用 .check() 提取响应中的令牌,并用saveAs将其存入每个虚拟用户独立的Session中,后续请求通过 ${accessToken}来引用。

文章来源:卓码软件测评

精彩推荐:点击蓝字即可
软件负载测试API自动化测试软件测试第三方软件测试软件性能测试软件测试机构

使用令牌调用认证API

.exec( http("获取用户资料") .get("/api/user/profile") .header("Authorization", "Bearer ${accessToken}") // 从Session动态注入令牌 .check(status.is(200)) )

令牌自动刷新

需要在令牌失效前主动刷新。

主动刷新在业务请求前检查并刷新

在业务操作前,通过计算判断令牌是不是需要刷新。

// 假设令牌有效期为3600秒,我们设置阈值在剩余300秒时刷新 .exec(session => { val loginTime = session("loginTime").as[Long] val currentTime = System.currentTimeMillis() / 1000 val tokenAge = currentTime - loginTime val shouldRefresh = session.contains("refreshToken") && tokenAge > (3600 - 300) session.set("shouldRefreshToken", shouldRefresh) }) .doIf("${shouldRefreshToken}") { // 条件执行刷新 exec( http("刷新访问令牌") .post("/auth/refresh") .body(StringBody("""{"refresh_token":"${refreshToken}"}""")).asJson .check( jsonPath("$.access_token").saveAs("accessToken"), jsonPath("$.refresh_token").optional.saveAs("refreshToken") // 更新refresh_token ) ) .exec(session => { // 重置登录时间 println(s"用户 ${session("username").as[String]} 令牌已刷新") session.set("loginTime", System.currentTimeMillis() / 1000) .remove("shouldRefreshToken") }) }

被动刷新处理401未授权响应

当令牌已过期,请求返回401时,进行刷新并重试。

import io.gatling.commons.validation.Validation import io.gatling.core.action.builder.FeedBuilder // 定义刷新令牌的链,可重用 val refreshTokenChain = exec( http("被动刷新令牌") .post("/auth/refresh") .body(StringBody("""{"refresh_token":"${refreshToken}"}""")).asJson .check( jsonPath("$.access_token").saveAs("accessToken"), jsonPath("$.refresh_token").optional.saveAs("refreshToken") ) ) // 在可能失败的请求中尝试恢复 .exec( http("安全调用敏感API") .get("/api/sensitive/data") .header("Authorization", "Bearer ${accessToken}") .check(status.in(200, 401)) // 允许401 .check( // 如果是401,触发特定处理 status.is(401).saveAs("isUnauthorized") ) ) .doIf("${isUnauthorized}") { exec(refreshTokenChain) .exec( // 重试原请求 http("安全调用敏感API - 重试") .get("/api/sensitive/data") .header("Authorization", "Bearer ${accessToken}") .check(status.is(200)) ) .exec(session => session.remove("isUnauthorized")) }

模拟并发用户和会话

不同用户有不同的认证状态和行为。

模拟混合用户类型

// 定义不同用户情形 val registeredUserScenario = scenario("已注册用户") .exec(loginScenario) // 复用登录流程 .exec(/* 已认证用户的操作 */) val guestUserScenario = scenario("访客用户") .exec(/* 无需登录的公共操作 */) // 在同一个测试中注入不同比例的用户 setUp( registeredUserScenario.inject( rampUsers(100).during(30) ), guestUserScenario.inject( rampUsers(50).during(30) ) ).protocols(httpProtocol)

模拟用户登出和会话清理

.exec( http("用户登出") .post("/auth/logout") .header("Authorization", "Bearer ${accessToken}") .check(status.is(204)) ) .exec(session => { println(s"用户 ${session("username").as[String]} 已登出") session.removeAll("accessToken", "refreshToken", "loginTime") // 清理会话中的敏感数据 })

建议

令牌刷新方法

避免:不要所有用户在同一时间刷新。引入随机延迟:.pause(Random.nextInt(10).seconds)。

区分短令牌和长令牌:在Session中分开存储,使用不同刷新思路。

Session管理

最小化Session数据:只存储必要数据,避免内存过度使用。

使用.transform预处理数据:在Feeder读取数据时即完成清洗和格式化。

及时清理:在登出或会话结束时,使用.remove或.removeAll清理敏感数据。

并发控制和资源管理

限制最大并发刷新数:使用throttle限制令牌刷新端点压力。

setUp( loginScenario.inject(rampUsers(1000).during(60)) ).throttle( reachRps(50).in(10), // 限制刷新接口最大50 RPS holdFor(2 minutes) )

监控虚拟用户状态:通过Gatling日志或自定义钩子记录异常。

调试

记录重点信息:在.exec中打印令牌片段和状态。

证实Session状态:使用session => { println(session); session } 调试。

检查响应完整性:保证刷新后新令牌被正确存储。

Gatling实现认证会话管理是将令牌生命周期管理、条件性执行思路、差别化用户模拟和健壮的错误处理进行有机结合。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:10:11

30分钟搭建VS2015密钥验证API原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个VS2015密钥验证API原型,功能包括:1. RESTful API接口;2. 密钥格式验证;3. 模拟微软验证服务;4. 返回验证结果。…

作者头像 李华
网站建设 2026/4/18 5:43:57

QWEN3如何革新AI辅助编程体验?

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 使用QWEN3模型开发一个智能代码生成器,能够根据自然语言描述自动生成Python代码。要求支持以下功能:1. 根据用户输入的功能描述生成可运行的代码片段&#…

作者头像 李华
网站建设 2026/4/18 10:50:23

系统管理员必备:BLUESCREENVIEW实战排查案例集

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个包含多个蓝屏故障案例分析的交互式教程。每个案例应包括:1. 错误截图 2. BLUESCREENVIEW分析过程 3. 问题定位 4. 解决方案 5. 预防措施。要求使用Markdown格式…

作者头像 李华
网站建设 2026/4/18 7:37:45

用AI背单词神器:不背单词网页版智能学习法

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个AI辅助背单词的网页应用,包含以下功能:1. 基于用户记忆曲线智能安排复习时间;2. 语音识别功能,可以跟读并评分;…

作者头像 李华
网站建设 2026/4/18 8:50:04

传统vs深度学习:2D骨骼检测方案对比,云端快速验证

传统vs深度学习:2D骨骼检测方案对比,云端快速验证 引言:为什么需要骨骼关键点检测? 想象一下,当你观看一段舞蹈视频时,大脑能自动识别出舞者的手肘、膝盖等关节位置,并据此理解动作含义。骨骼…

作者头像 李华
网站建设 2026/4/18 8:30:23

AI+虚仿 智慧教育引领淡水渔业智慧养殖专业新双高建设

随着新一轮科技革命与产业变革的深入发展,智慧教育、人工智能(AI)、虚拟仿真(虚仿)等技术正深刻重塑职业教育生态。《关于推动现代职业教育高质量发展的意见》《关于深化现代职业教育体系建设改革的意见》等政策明确要…

作者头像 李华