Play中的“助手”并检查用户是否在视图中进行了身份验证

时间:2014-01-09 06:45:35

标签: scala playframework playframework-2.2

我有一个身份验证特征:

trait MyAuth {
  private def login(request: RequestHeader) = request.session get "email"

  private def onUnauthorised = Results.Redirect(routes.Session.add)

  def isAuthenticated(f: => String => Request[AnyContent] => Result) =
    Security.Authenticated(login, _ => onUnauthorised) { userEmail =>
      Action(request => f(userEmail)(request))
    }
}

我想创建一个登录框 - 局部视图。

1)如何在登录框内检查用户是否已通过身份验证?这样的事情:

@if (userIsAuthenticated) {
  Hello @userName ! <a href="@routes.Session.destroy()">Logout</a>
} else {
  <a href="@routes.Session.add()">Login</a>
}

2)总的来说,Play中有助手吗?类似于Ruby on Rails中的帮助程序 - 我自己创建的函数,我可以在视图中调用它?

1 个答案:

答案 0 :(得分:0)

1)

您在模板中使用的任何有状态信息都必须使用参数传入。这一开始看起来很不方便,但是你很快就习惯了它,它使模板变得简单和简单,因为你总能知道行为的来源。

经常使用的请求“上下文”信息可以通过隐式参数方便地传递给模板(并从那里传递到子模板)。例如,我做这样的事情:

// Class to contain custom request "context"
case class Context(email: Option[String])

// Your code...
trait MyAuth {
  private def login(request: RequestHeader) = request.session get "email"

  private def onUnauthorised = Results.Redirect(routes.Session.add)

  def isAuthenticated(f: => Context => Request[AnyContent] => Result) =
    Security.Authenticated(login, _ => onUnauthorised) { userEmail =>
      Action(request => f(Context(Some(userEmail)))(request))
    }
}

使用带有一些隐式参数的模板,如:

@()(implicit context: Context, request: RequestHeader, lang: Lang)

@context.email.map { email =>
  Hello @email ! <a href="@routes.Session.destroy()">Logout</a>
}.getOrElse {
  <a href="@routes.Session.add()">Login</a>
}

然后在控制器中使用它时:

def myAction = isAuthenticated { implicit context => implicit request =>
   Ok(views.html.myTemplate) // context added automatically
}

请注意,您还可以使用WrappedRequest将其他操作数据封装在撰写的操作中。

通过隐式参数传递模板上下文的好处是,当您必须在每个模板的参数列表中指定它们时,编译器将在调用模板函数时自动添加它们,即:

/* main.scala.html */
@(title: String)(content: Html)(implicit context: Context, request: RequestHeader, lang: Lang)

<html>
    <head><title>@title</title></head>
    <body>
        <div class="header">
            @context.email.map { email =>
                Hello: @email
            }.getOrElse {
                Please log in
            }
        </div>
        <div class="main">
            @content
        </div>
    </body>
</html>

然后从顶级模板调用它:

/* mypage.scala.html 

   See how compiler adds implicit params when calling `main` template.
*/
@(title: String)(content: Html)(implicit context: Context, request: RequestHeader, lang: Lang)

@main("My Page") {
    <h1>Welcome to my page</h1>
}

2)

对于一般的辅助函数,您可以在Helpers包中粘贴一个名为app.views的对象,即:

/* app/views/Helpers.scala  */
object Helpers {

   def prettyTime(time: DateTime): String = ...
}

然后在视图中将其称为@views.Helpers.prettyTime(dateTime),或使用@import views.Helpers._导入模板顶部的所有帮助。