为了确保人们不会附加随机查询参数(例如附加&r=234522.123
或类似参数)以避免命中我们的缓存,我希望有一种方法可以拒绝任何未明确处理的查询。我当然可以创建一个包含白名单的列表,但这必须单独维护,而且我讨厌维护需要保持同步的两件事。(不过,它有助于更快地失败。)喷雾路由是否可以做到这一点?
问问题
270 次
3 回答
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")
}
}
于 2014-03-11T22:49:09.950 回答
1
实际上,你有一个很好的解决方案,我只能建议一个小的重构:
def only(params: String*): Directive0 = {
def check: Map[String, String] => Boolean = _.keySet diff params.toSet isEmpty
parameterMap.require(check, rejection)
}
你可以把它写成一个单行,但它会更长
于 2014-03-12T17:45:01.717 回答
-2
使用这样的路线:
val myRoute = {
...
pathPrefix("test") {
parameter("good") {
good =>
complete("GOOD")
}
} ~
...
}
Spray 将要求第一个参数是good
并且具有值,即?good=value
。不允许其他有值的参数。
于 2014-03-03T20:16:44.470 回答