指令在 akka-http 中同时使用请求 header 和 body

Directive use both request header and body in akka-http

对于某些 API 调用中的签名验证,我必须从请求 body 中计算 Signature 并将其与 [=28] 中的签名进行比较=].由于我找不到任何预定义指令可以完成这项工作,我想出了一个这样的自定义指令:

def verifySignature(channelSecret: String): Directive0 =
headerValueByName("X-Line-Signature").flatMap { signature =>
  entity(as[String]).flatMap { bodyString =>
    if (computeSignature(channelSecret, bodyString) == signature) pass
    else reject
  }
}

这按预期工作。

所以我只是想知道是否可以做得更好。 有什么指令可以更好地完成这项工作吗? 使用 pass 是否正确?

我觉得这很好。 pass 是结束你的 Directive0 的正确方法,它被更复杂的 Akka HTTP 指令使用(一个随机的例子,method 指令)。

据我所知,没有特定指令可用于执行您需要的任务。而且这是非常简单地构建为自定义指令,可能不应该存在。

您可以进行一些微小的改进:

  1. 您应该以适当的拒绝方式拒绝 - 以便通过适当的响应 + 状态代码更轻松地处理它们

  2. 您可以使用 &

  3. 展平 2 个嵌套指令

  def verifySignature(channelSecret: String): Directive0 =
    (headerValueByName("X-Line-Signature") & entity(as[String])).tflatMap{
      case (signature, body) if computeSignature(channelSecret, body) == signature => pass
      case _ => reject(ValidationRejection("Invalid signature"))
    }