为确保人们不附加随机查询参数(例如附加&r=234522.123
或类似内容)以避免命中我们的缓存,我希望有办法拒绝任何未明确处理的查询。我当然可以创建一个包含白名单的内容,但是必须单独维护,我讨厌维护需要保持同步的两件事。 (尽管如此,它有助于更快地失败。)喷涂路由是否可行?
答案 0 :(得分:1)
我最终得到了这个:
// This contains a white-list of allowed query parameters. This is useful to
// ensure people don't try to use &r=234234 to bust your caches.
def allowedParameters(params: String*): Directive0 = parameterSeq.flatMap {
case xs =>
val illegal = xs.collect {
case (k, _) if !params.contains(k) => k
}
if (illegal.nonEmpty)
reject(ValidationRejection("Illegal query parameters: " + illegal.mkString("", ", ", "\nAllowed ones are: ") + params.mkString(", ")))
else
pass
}
如需使用,请查看单元测试:
val allowedRoute = {
allowedParameters("foo", "bar") {
complete("OK")
}
}
"Allowed Parameter Directive" should "reject parameters not in its whitelist" in {
Get("/?foo&bar&quux") ~> allowedRoute ~> check {
handled should equal(false)
rejection should be(ValidationRejection("Illegal query parameters: quux\nAllowed ones are: foo, bar"))
}
}
it should "allow properly sorted parameters through" in {
Get("/?bar&foo") ~> allowedRoute ~> check {
handled should equal(true)
responseAs[String] should equal("OK")
}
}
答案 1 :(得分:1)
实际上,你有一个很好的解决方案,我只能建议一个小的重构:
def only(params: String*): Directive0 = {
def check: Map[String, String] => Boolean = _.keySet diff params.toSet isEmpty
parameterMap.require(check, rejection)
}
你可以把它写成一个单行,但它会更长
答案 2 :(得分:-2)
使用这样的路线:
val myRoute = {
...
pathPrefix("test") {
parameter("good") {
good =>
complete("GOOD")
}
} ~
...
}
Spray将要求第一个参数为good
并具有值,即?good=value
。不允许其他具有值的参数。