Why does authorize directive execute after the cod

2019-07-22 13:07发布

问题:

I am using Scala 2.11.2, Akka 2.3.6 and Spray 1.3.2.

I'm facing an issue with the authorize directive. Here is the interesting part of the code:

val authenticatorActor = context.actorOf(Props[AuthenticatorActor])
implicit val timeout = Timeout(5 seconds)

cookie("userName") { cookie =>
  def optionUser = Await.result(authenticatorActor ? cookie.content, timeout.duration).asInstanceOf[Option[User]]
  authorize(isAuthorized(optionUser)) { // ?????
    val user = optionUser.get
    //do stuff
  }
}

def isAuthorized(user: Option[User]): Boolean = 
  user match {
    case Some[User] => true
    case None       => false
  }

Basically, I check the cookie to validate the user credentials.

The problem is that the block inside the authorize directive is executed before the isAuthorize method.

So if the future returns a None, code fails in val user = optionUser.get with an ugly NonSuchElementException.

If the authorize directive is changed by an if statement like in the snippet below all work fine:

if (isAuthorized(optionUser)) {
  //do stuff 
} else reject(ValidationRejection("User has not access")) 

Any idea?

UPDATE

I'm adding the //do stuff block for reference

get {
  path("") {
    complete {
      s"Hi ${user.name}. You have the next access: ${user.acceso}.\nWelcome to the ping-pong match" 
    }
  } ~
  path("ping") {
    complete("pong")
  } ~
  path("pong") {
    complete ("ping")
  }
}

回答1:

Thanks to Gangstead and user3567830 for the answere.

As states in the docs

http://spray.io/documentation/1.2.2/spray-routing/advanced-topics/understanding-dsl-structure/#understanding-extractions

The correct way is like this:

authorize(isAuthorize(optionUser)) {
        get {
          path("") {
            complete {
              val user = optionUser.get
              s"Hi ${user.name}. You have the next access: ${user.acceso}.\nWellcome to the ping-pong match"
            }
          }
       }
            ....


标签: scala akka spray