scala - 相当于akka-http中的认证路由?

标签 scala authentication playframework

这可能是一个有点菜鸟的问题,因为我才刚刚开始玩。我们可以在 akka-http 中找到的经过身份验证的路由的等效项是什么?下面是使用 akka-http 进行身份验证的路由的示例

def oauth2Authenticator(credentials: Credentials): Future[Option[ScalaFirebaseToken]] = {
    credentials match {
      case p @ Credentials.Provided(token) =>
          ImportFirebaseCredentials.decodeToken(token).flatMap {
            case token : FirebaseToken => {
              Future(Some(
                ScalaFirebaseToken(token.getUid,
                  Option(token.getEmail),
                  Option(token.getName),
                  Option(token.getPicture)
                )))
            }
            case _ => Future.successful(None)
          }
      case _ =>
        println("couldn't obtain credentials")
        Future.successful(None)
    }
  }

  def authenticated = authenticateOAuth2Async("auth", oauth2Authenticator)

  val route =
    path("user") {
      (get & authenticated) { authResult =>
        complete(getUserByUid(authResult.uid, authResult.email, authResult.name))
      }
    }

此代码从请求 header 获取凭据,根据 Firebase 进行检查,然后返回该用户的数据。

我很想得到一个例子来说明如何以类似的方式验证我的行为。

最佳答案

可以使用 action composition 来实现经过身份验证的路由。这是取自 playframework/play-scala-secure-session-example 的一个示例它使用 ActionBuilder 通过 UserInfoAction.invokeBlock 实现身份验证:

override def invokeBlock[A](request: Request[A], block: (UserRequest[A]) => Future[Result]): Future[Result] = {
  // deal with the options first, then move to the futures
  val maybeFutureResult: Option[Future[Result]] = for {
    sessionId <- request.session.get(SESSION_ID)
    userInfoCookie <- request.cookies.get(USER_INFO_COOKIE_NAME)
  } yield {
    // Future can be flatmapped here and squished with a partial function
    sessionService.lookup(sessionId).flatMap {
      case Some(secretKey) =>
        val cookieBaker = factory.createCookieBaker(secretKey)
        val maybeUserInfo = cookieBaker.decodeFromCookie(Some(userInfoCookie))

        block(new UserRequest[A](request, maybeUserInfo, messagesApi))
      case None =>
        // We've got a user with a client session id, but no server-side state.
        // Let's redirect them back to the home page without any session cookie stuff.
        Future.successful {
          discardingSession {
            Redirect(routes.HomeController.index())
          }.flashing(FLASH_ERROR -> "Your session has expired!")
        }
    }
  }

  maybeFutureResult.getOrElse {
    block(new UserRequest[A](request, None, messagesApi))
  }
}

如果身份验证成功,请求将通过 maybeUserInfo 进行丰富,而如果失败,则会在 Flash 中添加一个带有 您的 session 已过期 的重定向。现在,要将身份验证添加到路由,只需将 UserInfoAction 注入(inject) Controller 和 call it像这样:

def login = userAction.async { implicit request: UserRequest[AnyContent] =>
  ...
  // request.userInfo is now available
} 

关于scala - 相当于akka-http中的认证路由?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50670471/

相关文章:

大型 WSDL( Play Framework )上的 Java 内存不足错误

scala - 为什么 "((left union right) union other)"没有关联行为?

scala - 奇怪的 "match may not be exhaustive"警告

java - org.apache.http.client.ClientProtocolException异常

postgresql - 使用 Play Framework Anorm,如何获取插入时自动生成的 id?

https - Play 框架提供 HTTPS 内容

performance - Scala支持尾递归优化吗?

scala - Intellij IDEA 无法识别 Play 2.0 功能

python - 从 django-social-auth 移植到 python-social-auth 时,现场用户的访问器发生冲突

php - 使用路由的 Laravel 5.1 页面身份验证