播放2.2.x,带有身份验证和请求扩展的动作组合

时间:2014-03-18 14:35:08

标签: mongodb scala playframework playframework-2.2 reactivemongo

我正在尝试创建一个ActionBuilder来检查用户是否已登录,如果是,则将用户对象添加到请求(AuthenticatedRequest)。使用MySQL这很容易,因为解析用户不会得到Future对象。但在这种特殊情况下,我们使用带有ReactiveMongo for Play的MongoDB,它会返回未来值。

到目前为止,我已经在这里制作了这个小片段。但它让我觉得类型不匹配:

  

类型不匹配;发现:scala.concurrent.Future [Option [models.User]] => scala.concurrent.Future [Object] required:Object => ?

object Authenticated extends ActionBuilder[AuthenticatedRequest] {


def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
    import models.User
    (for{
      sID <- request.session.get("sessionID")
      code <- request.session.get("otherCode")
      user: Future[Option[User]] <- models.Session.getUserBySessionAndCode(sID, code)
    } yield {
      (for{
        uAbs <- user
      } yield {
        if(uAbs.isDefined) {
          block(AuthenticatedRequest(uAbs.get, request))
        }else{
          BadRequest
        }
      })
    }).getOrElse(Future.successful(BadRequest))
  }
}

你知道如何从这里继续前进吗?也许这甚至是错误的方法。 谢谢!

1 个答案:

答案 0 :(得分:1)

如何将步骤分成更小的块并按照您期望的类型显式键入它们,这样它会更清晰,您将找到您的想法和所写内容的不同方向,例如:

def userFromRequest(request: Request): Future[Option[User]] = 
  for{
    sID <- request.session.get("sessionID")
    code <- request.session.get("otherCode")
    maybeUser <- models.Session.getUserBySessionAndCode(sID, code)
  } yield maybeUser

def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
  userFromRequest(request).flatMap {
    case None => Future.successful(BadRequest)
    case Some(user) => block(AuthenticatedRequest(user, request))
  }
}