Клиенту отправлен неправильный отказ

У меня есть маршруты без проверки подлинности и маршруты с проверкой подлинности в моем Akka/Spray DSL. Ниже приведен упрощенный вариант кода

val nakedRoutes = pathPrefix("user") {
  post {
    entity(as[UserNew]) { user =>
      (validate(EmailValidator.getInstance().isValid(user.email), s"Invalid email address ${user.email}") & validate(!user.password.isEmpty, "Password should not be empty")) {
          complete {
            UserWire(new ObjectId(), user.firstName, user.lastName, user.email, user.company, user.role, new ObjectId())
            }
        }
    }
  }
}

val myAuthorization: Directive[Tuple1[String]] = (headerValueByName("X-API-Token") | parameter("token")).tflatMap[Tuple1[String]]{
    case Tuple1(token) => if (!token.isEmpty) provide(token.reverse) else complete(StatusCodes.Forbidden -> "API token is not provided")
  }

val authenticatedRoutes = myAuthorization { user =>
  get { complete { "" } }
}

val routes = (decodeRequest & encodeResponse) {
    authenticatedRoutes ~ nakedRoutes
  }

Идея состоит в том, что пользователь делает POST /user запрос, получает токен и использует его для аутентифицированных маршрутов.

У меня проблема в том, что при сбое проверки электронной почты я получаю неправильный отказ

Request is missing required HTTP header 'X-API-Token'

Почему он не выдает последний отказ? Как он выбирает, какое отклонение вернуть клиенту?

Я, вероятно, могу проверить электронную почту вручную с помощью if-else и вернуть пользовательский complete{}, но я не уверен, что это правильный подход с akka-http.


person expert    schedule 05.08.2015    source источник


Ответы (1)


Что ж, изменение myAuthorization на следующий код помогло, но я не понимаю, почему :) Если @roland-kuhn или @jrudolph могут прокомментировать это, я был бы очень признателен.

Если я ссылаюсь на старый документ Spray Я ожидаю, что отклонения, сгенерированные myAuthorization, будут отменены, потому что директива post разрешила прохождение запроса.

val myAuthorization: Directive[Tuple1[String]] = (headerValueByName("X-API-Token") | parameter("token")).tflatMap[Tuple1[String]]{
  case Tuple1(token) => if (!token.isEmpty) provide(token.reverse) else complete(StatusCodes.Forbidden -> "API token is invalid")
}.recover {
  case rejections => reject(ValidationRejection("API token is not provided"))
}
person expert    schedule 05.08.2015