自定义spray.io指令以验证请求标头值

时间:2016-07-20 23:52:20

标签: scala spray

我是新手,我正在尝试编写自定义指令。如果标头值无效,我希望该指令拒绝该请求,否则单独留下请求。

我试图吸收这个页面: http://spray.io/documentation/1.1.2/spray-routing/key-concepts/directives/

具体来说,关于响应者链的部分。我试图在插图中的条形指令层面创建一些东西。我只是没有得到如何将上下文不变地传递到内部路径。

下面我的其他阻止不正确,但表达了我想要做的事情。我无法弄清楚如何实现它。

非常感谢任何帮助。

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

2 个答案:

答案 0 :(得分:2)

你可以结合使用

headerValueByName

def headerValueByName(headerName: String): Directive1[String]

validate

def validate(check: ⇒ Boolean, errorMsg: String): Directive0

例如:

  def validateApiKey(route: Route) =
    headerValueByName("api-key") { key =>
      validate(key == "123", "Invalid API key") {
        route
      }
    }

或没有validate

  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"

答案 1 :(得分:0)

  

我还没有得到如何将上下文不变地传递给内部   路由。

Spray为你做到了!

您的代码大多是正确的,只有2个简单的问题需要解决! 首先,您需要flatMap headerValueByName("api-key")指令。 其次,返回类型将为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密钥无效时会收到通知。