4

我有以下用例。我在我的 play 应用程序中实现了一个非常简单的身份验证,如果用户登录,它会添加一个会话 cookie(参见下面的代码)。

到目前为止,此代码运行良好。我现在想要实现的是检查我的主模板是否有用户登录,并根据用户状态在页面上显示登录/注销元素。

我怎样才能以最优雅的方式实现这一目标?

我找到了人们使用 play <= 2.1 直接从模板访问会话变量的来源。似乎这种方法不再适用于 2.2 并且已被弃用?我是否必须在每个操作中将布尔值传递给模板来定义用户是否登录?

包装器动作

case class Authenticated[A](action: Action[A]) extends Action[A] {

  def apply(request: Request[A]): Future[SimpleResult] = {
    if (request.session.get("user").getOrElse("").equals("user")) { 
      action(request) 
    } else {
      Future.successful(Redirect("/login").withSession(("returnUrl", request.path)))
    }
  }

  lazy val parser = action.parser
}

提交登录控制器的一部分

def submit = Action { implicit request =>
  loginForm.bindFromRequest.fold(
    errors => Ok(html.login.form(errors)),
    requestUser => {
      val user: String = Play.current.configuration.getString("fillable.user").getOrElse("")
      val password: String = Play.current.configuration.getString("fillable.password").getOrElse("")
      if (requestUser.name.equals(user) && requestUser.pw.equals(password))
        Redirect(request.session.get("returnUrl").getOrElse("/")).withSession(session + ("user" -> requestUser.name) - "returnUrl")
      else
        Ok(html.login.form(loginForm, "error", Messages("error.wrongCredentials")))
    })
}

需要身份验证的示例控制器操作

def submit = Authenticated {
  Action.async { implicit request =>
    ...
  }
}
4

1 回答 1

0

所以我现在发现的是,如果控制器操作使用隐式请求(如我上面问题中的请求),我可以使用该请求,因此如果我将其添加到模板的头部,我可以使用我的模板中的会话:

(implicit request: Request[Any])

我不确定这是否是一个好方法,所以如果有人可以批准,我很高兴。

于 2013-10-30T08:38:05.310 回答