使用 WS 和 ScalaTest 发送 auth cookie

Sending auth cookie using WS and ScalaTest

我有一个使用表单登录的网络应用程序,这个 returns 一个给用户的会话 cookie,用于授权对应用程序其余部分的请求。我无法通过我的请求发送此 cookie 值。我的测试工具如下:

val loginResponse = await(WS.url(s"http://localhost:$port/authenticate")
  .withHeaders("Content-Type" -> "application/x-www-form-urlencoded")
  .post(Map("email" -> Seq("admin@example.com"), "password" -> Seq("genivirocks!"))))
loginResponse.status mustBe (OK)
val cookies = loginResponse.cookies(0).toString
val vehiclesResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles/" + testVin)
  .withHeaders("Cookie" -> cookies)
  .put(""))
vehiclesResponse.status mustBe (OK)
val vehiclesFilterResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles?regex=" + testVin)
  .withHeaders("Cookie" -> cookies)
  .get())
vehiclesFilterResponse.status mustBe (OK)

请求失败,因为第二个请求获得 204 而不是 200,因为它被重定向到登录页面,因为 cookie 被解释为无效。当发出第二个请求时,Web 服务器给出以下错误:

2015-10-06 14:56:15,991 [sota-core-service-akka.actor.default-dispatcher-42] WARN akka.actor.ActorSystemImpl - Illegal request header: Illegal 'cookie' header: Invalid input 'EOI', expected tchar, '\r', WSP or '=' (line 1, column 178): PLAY2AUTH_SESS_ID=ee84a2d5a0a422a3e5446f82f9f3c6f8eda9db1cr~jz7ei0asg0hk.ebd8j.h4cpjj~~9c0(yxt8p*jqvgf)_t1.5b(7i~tly21(*id; path=/; expires=1444139775000; maxAge=3600s; HTTPOnly

我已经尝试自己构建 cookie 字符串并确保末尾没有额外的 '\r' 字符等等,但没有成功。 Google 似乎也没有任何提示。有没有更好的方法使用 WS 发送 cookie 值?

编辑

通过以下代码得到它:

import play.api.mvc.Cookies

val loginResponse = ...
loginResponse.status mustBe (OK)
val cookies = loginResponse.cookies
val cookie = Cookies.decodeCookieHeader(loginResponse.cookies(0).toString)
val vehiclesResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles/" + testVin)
  .withHeaders("Cookie" -> Cookies.encodeCookieHeader(cookie))
  .put(""))
vehiclesResponse.status mustBe (OK)
...

为什么不使用现有的 Cookies.encode 函数为您进行 cookie 编码?

import play.api.mvc.Cookies

val loginResponse = ...
loginResponse.status mustBe (OK)
val cookies = loginResponse.cookies
val vehiclesResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles/" + testVin)
  .withHeaders("Cookie" -> Cookies.encode(cookies))
  .put(""))
vehiclesResponse.status mustBe (OK)
...