Scala 用于验证请求标头值的自定义spray.io指令

Scala 用于验证请求标头值的自定义spray.io指令,scala,spray,Scala,Spray,我是喷雾剂新手,我正在尝试编写一个自定义指令。如果标头值无效,我希望该指令拒绝该请求,否则不要处理该请求 我试着理解这一页: 特别是关于响应者链的部分。我试图在图中的bar指令级别创建一些东西。我只是不知道如何将上下文不变地传递给内部路径 下面我的else块不正确,但表达了我试图做的事情。我就是不知道如何实现它 任何帮助都将不胜感激 trait ApiKeyDirective { import spray.routing.directives.HeaderDirectives._

我是喷雾剂新手,我正在尝试编写一个自定义指令。如果标头值无效,我希望该指令拒绝该请求,否则不要处理该请求

我试着理解这一页:

特别是关于响应者链的部分。我试图在图中的bar指令级别创建一些东西。我只是不知道如何将上下文不变地传递给内部路径

下面我的else块不正确,但表达了我试图做的事情。我就是不知道如何实现它

任何帮助都将不胜感激

trait ApiKeyDirective {
    import spray.routing.directives.HeaderDirectives._
    import spray.routing.directives.BasicDirectives._

    def validateApiKey(): Directive1 = {

       headerValueByName("api-key") {key =>
           val valid = key == "123"
           if (!valid) reject() else pass
       }
    }
}

object ApiKeyDirective extends ApiKeyDirective
我只是不知道如何将上下文不变地传递给内部 路线

喷雾剂可以帮你

您的代码基本正确,只有两个简单的问题需要解决! 首先,您需要
flatMap
headerValueByName(“api键”)
指令。 其次,返回类型将是
Directive0
,因为该指令不提供任何值

最后的代码如下所示:

object ApiKeyDirective {
  import spray.routing.Directives._

  val validateApiKey: Directive0 =
    headerValueByName("api-key").flatMap { key =>
      val valid = key == "123"
      if (!valid) reject() else pass
    }

}
另外,我建议您在
reject()
块中添加一个自定义拒绝,以便API用户在其API密钥无效时得到通知。

您可以合并

:

与:

例如:

  def validateApiKey(route: Route) =
    headerValueByName("api-key") { key =>
      validate(key == "123", "Invalid API key") {
        route
      }
    }
或不使用
验证

  def validateApiKey(route: Route) =
    headerValueByName("api-key") { key =>
      if (key == "123")
        route
      else
        reject(ValidationRejection("Invalid API key"))
    }
用法:

lazy val route = ...
    ... ~
    pathPrefix("test_directive") {
      get {
        validateApiKey {
          complete("ok")
        }
      }
    } ~
    ...
从cmd/shell进行测试:

# curl http://localhost:8080/test_directive
Request is missing required HTTP header 'api-key'

# curl http://localhost:8080/test_directive -H 'api-key: bad'
Invalid API key

# curl http://localhost:8080/test_directive -H 'api-key: 123'
"ok"

谢谢我打算以授权拒绝,但出于简洁起见,我将其省略了。谢谢。看到可能的变化真的很有帮助。
lazy val route = ...
    ... ~
    pathPrefix("test_directive") {
      get {
        validateApiKey {
          complete("ok")
        }
      }
    } ~
    ...
# curl http://localhost:8080/test_directive
Request is missing required HTTP header 'api-key'

# curl http://localhost:8080/test_directive -H 'api-key: bad'
Invalid API key

# curl http://localhost:8080/test_directive -H 'api-key: 123'
"ok"