2016-07-20 12 views
2

Ich bin neu zu sprühen und ich versuche, eine benutzerdefinierte Richtlinie zu schreiben. Ich möchte, dass die Anweisung die Anfrage ablehnt, wenn der Kopfzeilenwert nicht gültig ist, andernfalls lassen Sie die Anfrage in Ruhe.Benutzerdefinierte spray.io-Anweisung zur Validierung der Anfrage Header-Wert

Ich habe versucht, diese Seite zu absorbieren: http://spray.io/documentation/1.1.2/spray-routing/key-concepts/directives/

Insbesondere der Teil über die Responder-Kette. Ich versuche etwas auf der Ebene der Bar-Richtlinie in der Abbildung zu schaffen. Ich verstehe nicht, wie man den Kontext unverändert an die innere Route weitergibt.

Mein else Block unten ist nicht korrekt, aber drückt aus, was ich versuche zu tun. Ich kann einfach nicht herausfinden, wie ich es umsetzen soll.

Jede Hilfe würde sehr geschätzt werden.

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 

Antwort

0

Ich erhalte nur nicht, wie der Zusammenhang mit der inneren Route unverändert passieren.

Spray macht das für Sie!

Ihr Code ist größtenteils korrekt, es gibt nur 2 einfache Probleme zu beheben! Zuerst müssen Sie flatMapheaderValueByName("api-key") Direktive. Zweitens ist der Rückgabetyp Directive0, da die Direktive keinen Wert liefert.

So endgültige Code würde wie folgt aussehen:

object ApiKeyDirective { 
    import spray.routing.Directives._ 

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

} 

Auch empfehle ich Ihnen, eine benutzerdefinierte Ablehnung reject() Block hinzuzufügen, so dass API-Nutzer informiert werden, wenn ihre api Schlüssel ungültig ist.

+1

Dank! Ich beabsichtige, mit einer AuthorizationFailedRejection abzulehnen, aber es aus Gründen der Prägnanz auszulassen. –

2

können Sie kombinieren

headerValueByName:

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

mit validate:

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

Zum Beispiel:

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

oder ohne validate:

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

Verbrauch:

lazy val route = ... 
    ... ~ 
    pathPrefix("test_directive") { 
     get { 
     validateApiKey { 
      complete("ok") 
     } 
     } 
    } ~ 
    ... 

-Test von 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" 
+0

Danke. Es ist sehr hilfreich, mögliche Variationen zu sehen. –

Verwandte Themen