我的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。
答案 0 :(得分:0)
好吧,将myAuthorization
更改为以下代码有帮助,但我不明白为什么:)如果@ roland-kuhn或@jrudolph可以对此发表评论,我会非常感激。
如果我引用old Spray's doc我希望取消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"))
}