Акка HTTP асинхронные директивы - PullRequest
0 голосов
/ 14 мая 2018

Я хотел бы реализовать асинхронное управление токенами сеанса на веб-сервере Akka на основе HTTP, прежде чем будет обработана серия разумных маршрутов.

В моей идее реализации у меня был бы метод, который выполняетаутентификация, которая будет выглядеть следующим образом:

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 классом обращения, обертывающим sessionToken, которыйЯ бы предоставил последующим маршрутам.Вместо точек приостановки я вынужден ждать результата 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, который также может предоставить какое-то значение, которое можно поместить внормальное определение маршрута?

1 Ответ

0 голосов
/ 14 мая 2018

Я думаю, что вы могли бы создать такую ​​директиву, как эта

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]

...