为啥加特林不将身份验证令牌从 POST 返回正文发布到 GET 标头

Posted

技术标签:

【中文标题】为啥加特林不将身份验证令牌从 POST 返回正文发布到 GET 标头【英文标题】:Why won't gatling post an auth token from a POST return body to a GET header为什么加特林不将身份验证令牌从 POST 返回正文发布到 GET 标头 【发布时间】:2020-11-17 05:50:23 【问题描述】:

我尝试了从该站点上的其他示例中找到的所有建议,但我仍然无法让我的 Gatling 测试将身份验证令牌从 POST 传递到以下 GET。令牌取自 POST 的返回正文,并作为标头传递给 GET

最初登录是在 BaseSimulationTest 中,但我把它放在 GetDealsTests 中进行故障排除

我尝试过的步骤:

    我添加了这个: //println(" Token value" + session("accessToken").as[String]) 而且我能够看到我在终端中得到了一个字符串,这似乎表明 accessToken 是一个空值 我尝试在方法和全局中声明 var accessValue 和 var accessToken。没有变化。 我尝试在传递令牌后检查 GET 上的标头值,但 .check(header.is(expected = $accessToken)) 似乎只是出错了 我已将登录 POST 和 GET 放在同一个方法,不同的方法等中 我尝试从 .formParam 中而不是在请求语句的正文中传递用户名和密码

我需要将标题作为地图吗?这是范围的事情吗?我需要以不同的方式声明变量吗?测试以“预期 200 但收到 401”类型的结果运行。我认为 POST 甚至没有看到传递给它的令牌。

class GetDealsTests extends BaseSimulationTest 

  def logIn2() = 
    exec(http("Log in")
      .post(getUrl() + "login")
      .header("Content-Type", "application/json")
      .body(ElFileBody("bodies/Login.json")).asJson
      .check(status.is(200))
      .check(jsonPath("$.access_token").saveAs("accessToken")))
        exec(
        session=>
          accessValue = session("accessToken").as[String]
          session
        )
  

  def getAllDeals() = 

    exec(_.set("accessToken", accessValue))
      .exec(
        http("Get all deals")
          .get("deals/all")
            .header("Authorization", "Bearer" + "$accessToken")
            .check(status.is(200))
          
      )
  


  val scnGetAllDeals = scenario("Get All Deals endpoint tests")
    .forever() 
      exec(logIn2())
      exec(getAllDeals())
    

  setUp(
    scnGetAllDeals.inject(
      nothingFor(5 seconds),
      atOnceUsers(users))

  ).protocols(httpConf.inferhtmlResources())
  .maxDuration(FiniteDuration(duration.toLong, MINUTES))

我查看了以下内容:Gatling won't save access token、Gatling Scala:Unable to send auth token to the method using session variable、Gatling - Setting Authorization header as part of request 并没有看到我做错了什么

【问题讨论】:

【参考方案1】:

很多东西:

    logIn2 和 getAllDeals 都缺少点以正确链接不同的方法调用。例如,以下是您的 logIn2 实际执行的操作(正确格式化有帮助):
def logIn2() = 
  val discardedResult = exec(http("Log in")
    .post(getUrl() + "login")
    .header("Content-Type", "application/json")
    .body(ElFileBody("bodies/Login.json")).asJson
    .check(status.is(200))
    .check(jsonPath("$.access_token").saveAs("accessToken")))
  return exec(
    session => 
      accessValue = session("accessToken").as[String]
      session
    )

    您可能不应该使用全局变量。你不需要它,而且这样的构造不是线程安全的,所以在负载下,虚拟用户将同时更新和读取这个引用,结果会一团糟。

    您的 Authorization 标头中在 Bearer 和实际值之间缺少一个空格。

    asJson 只是.header("Content-Type", "application/json") 的快捷方式,所以你设置了两次这个标题。

class GetDealsTests extends BaseSimulationTest 

  val logIn2 =
    exec(http("Log in")
      .post(getUrl() + "login")
      .body(ElFileBody("bodies/Login.json")).asJson
      .check(status.is(200))
      .check(jsonPath("$.access_token").saveAs("accessToken")))

  val getAllDeals =
     exec(
        http("Get all deals")
          .get("deals/all")
            .header("Authorization", "Bearer $accessToken")
            .check(status.is(200))
          
      )


  val scnGetAllDeals = scenario("Get All Deals endpoint tests")
    .forever 
      exec(logIn2)
      .exec(getAllDeals)
    

  setUp(
    scnGetAllDeals.inject(
      nothingFor(5 seconds),
      atOnceUsers(users))

  ).protocols(httpConf.inferHtmlResources())
  .maxDuration(FiniteDuration(duration.toLong, MINUTES))


【讨论】:

以上是关于为啥加特林不将身份验证令牌从 POST 返回正文发布到 GET 标头的主要内容,如果未能解决你的问题,请参考以下文章

为啥在通过 Firebase 身份验证传递 id 令牌时,此 CORS 身份验证的 Google Cloud 函数会返回 403?

在 django rest 框架中使用令牌身份验证返回更多信息

为啥 Spring 安全身份验证返回 Null 身份验证对象?

为啥 IIS 中的 Windows/集成身份验证不将用户凭据传递给 s-s-rS 和 SQL?

为啥基于令牌的身份验证更适合单页应用程序?

使用发布请求获取身份验证令牌