我希望在处理一系列合理路由之前,在基于Akka HTTP的Web服务器中实现异步会话令牌控制。
在我的实现思路中,我将有一个方法执行如下所示的身份验证:
def performAuthentication(sessionToken: String): Future[Result]
其中Result
是包含身份验证结果的案例类。为了执行身份验证,我想写一个可以放在合理路由之前的指令,如下所示:
def authenticate: Directive1[SessionToken] = optionalHeaderValueByName("session-token").flatMap {
case Some(sessionToken) if (...) => provide(SessionToken(sessionToken))
case _ => complete(StatusCodes.Unauthorized)
}
用SessionResult
一个case类包装sessionToken,我将提供给subsequents路由。取代暂停点,我被迫等待Promise
结果,因为如果我实现onComplete ... Success ... Failure
模式,如下所示:
onComplete(this.performAuthentication(sessionToken)) {
case Success(value) if (value.isAuthenticated) => provide(SessionToken(sessionToken))
case Failure(ex) => failWith(ex)
case _ => complete(StatusCodes.Unauthorized)
}
编译器警告我provide
和complete
会返回两种不同的类型......而且它是正确的。
我的问题是:有没有办法编写一个异步Directive
,它也可以提供一些值,可以放在正常的路由定义中?
答案 0 :(得分:0)
我认为您可以创建像这样的指令
type Token = String
def checkRequest(f: HttpRequest => Future[Token])(implicit ec: ExecutionContext): Directive1[Token] =
Directive { inner => ctx =>
val futureToken = f(ctx.request)
futureToken.flatMap(tkn => inner(Tuple1(tkn))(ctx))
}
您可以通过为其提供执行身份验证的功能来创建此指令。如果您想处理拒绝,Token
可能是Either[ErrorAuth, Token]