【问题标题】:Testing request with CSRF Token in Play framework 2.5 (Scala)在 Play 框架 2.5 (Scala) 中使用 CSRF 令牌测试请求
【发布时间】:2017-03-08 04:13:05
【问题描述】:

我的功能测试遇到了一个小问题。

我有戏! 2.5 scala 项目,其中我在某些表单上添加了 CSRF 验证,相关的 scala-test 单元测试失败,正如预期的那样,错误:

java.lang.RuntimeException: No CSRF token present!

我正在使用带有路由的 FakeRequest 来测试它们:

val fakeRequest   = FakeRequest(GET, s"/backOffice/login")
val Some(result)  = route(app, fakeRequest)

如何添加 CRSF 令牌以使我的测试再次成功?

(谢谢,抱歉英语不好,我不是本地人)

【问题讨论】:

  • 您可以覆盖 application.conf 并设置一些标题以绕过 CSRF,例如 here。或者看this的回答。
  • 您好,感谢您回答我!我应该准确地说我也在测试模板,并且我正在基于每个操作进行 CSRF 保护(文档中的第二种情况,而不是第一个带有过滤器的情况)。由于这个原因,我不能绕过 CSRF,因为我的模板需要一个 CSRF 令牌出现在 FakeRequest 中,就像我已经测试过的第二个链接一样(也应该精确,抱歉),但它适用于 2.2 .1,而 Intellij 对我大喊“无法解析符号 SignedTokenProvider”你知道我如何在 play 2.5 中做到这一点吗?
  • 找到了解决方案并做出了一个 trait :) 如果您有兴趣,请查看我添加的答案 ^^

标签: scala unit-testing playframework playframework-2.5


【解决方案1】:

更新:就像 haui 在他的评论中所说:

似乎他们在 2.6 版中添加了类似的东西。在那里你可以使用import play.api.test.CSRFTokenHelper._ FakeRequest().withCSRFToken(Scala)和CSRFTokenHelper.addCSRFToken(requestBuilder)(Java),如Migration guide中所述

对于仍在 2.5.6 中的人,我的回答仍然适用:

所以,在看了一段时间的 Play-scala 类之后,我终于找到了一种方法来调整这个答案:https://stackoverflow.com/a/19849420/4496364 to Play 2.5.6

我什至做了一个特质,所以如果有一天有人需要它,就在这里:

import play.api.Application
import play.api.test.FakeRequest
import play.filters.csrf.CSRF.Token
import play.filters.csrf.{CSRFConfigProvider, CSRFFilter}

import scala.language.postfixOps

trait CSRFTest {
  def addToken[T](fakeRequest: FakeRequest[T])(implicit app: Application) = {
    val csrfConfig     = app.injector.instanceOf[CSRFConfigProvider].get
    val csrfFilter     = app.injector.instanceOf[CSRFFilter]
    val token          = csrfFilter.tokenProvider.generateToken

    fakeRequest.copyFakeRequest(tags = fakeRequest.tags ++ Map(
      Token.NameRequestTag  -> csrfConfig.tokenName,
      Token.RequestTag      -> token
    )).withHeaders((csrfConfig.headerName, token))
  }
}

要使用它,只需用它扩展您的测试类,如下所示:

class LoginSpec extends PlaySpec with OneAppPerSuite /* or whatever OneApp */ with CSRFTest

然后,而不是调用

val fakeRequest = FakeRequest(/* params */)

只需调用

val fakeRequest = addToken(FakeRequest(/* params */))

我试图让它看起来像控制器中的 addToken{} :)

【讨论】:

  • 似乎他们在 play 2.6 版中添加了类似的东西。在那里你可以使用FakeRequest().withCSRFToken(Scala)和CSRFTokenHelper.addCSRFToken(requestBuilder)(Java),如Migration guide中所述
猜你喜欢
  • 2019-03-13
  • 2017-09-21
  • 2014-10-02
  • 1970-01-01
  • 2016-09-21
  • 1970-01-01
  • 2014-08-20
  • 2018-12-23
  • 1970-01-01
相关资源
最近更新 更多