在 Play 框架 2.5 (Scala) 中使用 CSRF 令牌测试请求
Testing request with CSRF Token in Play framework 2.5 (Scala)
我的功能测试遇到了一个小问题。
我有戏! 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 令牌才能使我的测试再次成功?
(谢谢,抱歉英语不好,我不是母语)
更新:就像 haui 在他的评论中所说的那样:
Seems like they added something similar in play version 2.6. There you can use import play.api.test.CSRFTokenHelper._
FakeRequest().withCSRFToken
(Scala) and CSRFTokenHelper.addCSRFToken(requestBuilder)
(Java) as explained in the Migration guide
对于还在 2.5.6 的人,我的回答仍然适用:
所以,在查看 Play-scala classes 一段时间后,我终于找到了一种方法来调整这个答案: 到 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,就像这样:
class LoginSpec extends PlaySpec with OneAppPerSuite /* or whatever OneApp */ with CSRFTest
然后,而不是调用
val fakeRequest = FakeRequest(/* params */)
直接打电话
val fakeRequest = addToken(FakeRequest(/* params */))
我试图让它看起来像控制器中的 addToken{} :)
我的功能测试遇到了一个小问题。
我有戏! 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 令牌才能使我的测试再次成功?
(谢谢,抱歉英语不好,我不是母语)
更新:就像 haui 在他的评论中所说的那样:
Seems like they added something similar in play version 2.6. There you can use
import play.api.test.CSRFTokenHelper._ FakeRequest().withCSRFToken
(Scala) andCSRFTokenHelper.addCSRFToken(requestBuilder)
(Java) as explained in the Migration guide
对于还在 2.5.6 的人,我的回答仍然适用:
所以,在查看 Play-scala classes 一段时间后,我终于找到了一种方法来调整这个答案: 到 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,就像这样:
class LoginSpec extends PlaySpec with OneAppPerSuite /* or whatever OneApp */ with CSRFTest
然后,而不是调用
val fakeRequest = FakeRequest(/* params */)
直接打电话
val fakeRequest = addToken(FakeRequest(/* params */))
我试图让它看起来像控制器中的 addToken{} :)