1

在 Play2 的 zentasks 示例中,我们有方法

def isAuthenticated(f: => String => Request[AnyContent] => Result) = {
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(request => f(user)(request))
  }
}

我想做的是添加另一种方法,如果我想直接从数据库中获取用户,我可以使用该方法。

必须在所有方法中添加包装器有点无聊

def method() = isAuthenticated { username => implicit request =>
  UserDAO.findOneByEmail(username).map { user =>
    Ok(html.user.view(user))
  }.getOrElse(Forbidden)
}

我是函数式编程的新手,所有这些=>都让我头晕目眩:)

有什么建议么?

4

3 回答 3

5

您可以定义另一个方法,例如IsAuthenticatedUser,它将采用类型的参数User => Request[AnyContent] => Result

def IsAuthenticatedUser(f: User => Request[AnyContent] => Result) = IsAuthenticated { email => request =>
  UserDAO.findOneByEmail(email).map { user =>
    f(user)(request)
  }.getOrElse(Forbidden)
}

然后,您可以按如下方式使用它:

def method = IsAuthenticatedUser { user => request =>
  Ok(html.user.view(user))
}
于 2012-04-13T20:53:01.730 回答
4

这是最终的解决方案

trait Secured {

  def username(request: RequestHeader) = request.session.get(Security.username)

  def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login)

  def withAuth(f: => String => Request[AnyContent] => Result) = {
    Security.Authenticated(username, onUnauthorized) { user =>
      Action(request => f(user)(request))
    }
  }

  def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request =>
    UserDAO.findOneByUsername(username).map { user =>
      f(user)(request)
    }.getOrElse(onUnauthorized(request))
  }

}

用法:

object Application extends Controller with Secured {

  def index = withAuth { username => implicit request =>
    Ok(html.index(username))
  }

  def user() = withUser { user => implicit request =>
    val username = user.username
    Ok(html.user(user))
  }
}

如您所见,如果会话不存在,用户将被重定向到特征中指定的登录页面。

如果在 DAO 中找不到用户名也是如此。

于 2012-04-14T07:00:27.590 回答
1

半解决方案是将获取用户数据的步骤封装到某个函数中并从模板级别调用它(而不是在每个操作上),因为每个模板只是一个 scala 函数。

多亏了这种方法,如果您有多个使用相同视图(甚至布局)的操作,您不必每次都获取登录用户,即:

user view

@defining(Application.getLoggedUser){ user =>
    @yourlayout("Welcome") {
        <h2>Hello @user.name</h2>
        ...
    } 
}
于 2012-04-13T16:29:26.383 回答