2

为了确保人们不会附加随机查询参数(例如附加&r=234522.123或类似参数)以避免命中我们的缓存,我希望有一种方法可以拒绝任何未明确处理的查询。我当然可以创建一个包含白名单的列表,但这必须单独维护,而且我讨厌维护需要保持同步的两件事。(不过,它有助于更​​快地失败。)喷雾路由是否可以做到这一点?

4

3 回答 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 回答