这是Play Framework中控制器的一个简单示例,其中每个操作都会检查会话 - 如果用户已登录。
object Application extends Controller {
def index = Action { implicit request =>
if (request.session.isEmpty) {
Redirect("/login")
} else {
Ok(views.html.index("index"))
}
}
def about = Action { implicit request =>
if (request.session.isEmpty) {
Redirect("/login")
} else {
Ok(views.html.index("about"))
}
}
}
我想在构造函数中处理会话检查而不是每个操作方法,但我只是不知道如何?看起来应该是这样的:
object Application extends Controller {
//This is where the constructor would check if session exists
//and if not - redirect to login screen
def index = Action {
Ok(views.html.index("index"))
}
def about = Action {
Ok(views.html.index("about"))
}
}
这是可能的,如果是,那么如何?
我的堆栈是Play Framework 2.2.1,Scala 2.10.3,Java 1.8.0-ea 64bit
更新 - 已解决感谢您的所有想法,现在找到了解决方案,请参阅我的回答。
答案 0 :(得分:9)
您可以利用Action Composition来实现这一目标。来自文档:
import play.api.mvc._
class AuthenticatedRequest[A](val username: String, request: Request[A]) extend WrappedRequest[A](request)
object Authenticated extends ActionBuilder[AuthenticatedRequest] {
def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) =>Future[SimpleResult]) = {
request.session.get("username").map { username =>
block(new AuthenticatedRequest(username, request))
} getOrElse {
Future.successful(Forbidden)
}
}
}
然后你可以这样做:
def index = Authenticated {
Ok(views.html.index("index"))
}
或者你可以设置一个过滤器(如@Robin Green建议的那样):
object AuthFilter extends Filter {
override def apply(next: RequestHeader => Result)(rh: RequestHeader): Result = {
rh.session.get("username").map { user =>
next(rh)
}.getOrElse {
Redirect("/login")
}
}
在Global.scala scala中,添加
override def doFilter(action: EssentialAction) = AuthFilter(action)
有关过滤器的更多信息,请参阅官方docs
答案 1 :(得分:4)
解决方案是使用Action Composition并创建自定义操作。
Auth.scala:
package core
import play.api.mvc._
import scala.concurrent._
import play.api.mvc.Results._
object AuthAction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
if (request.session.isEmpty) {
//authentication condition not met - redirect to login page
Future.successful(Redirect("/login"))
} else {
//proceed with action as normal
block(request)
}
}
}
Application.scala:
package controllers
import play.api._
import play.api.mvc._
import core._
object Application extends Controller {
def index = AuthAction {
Ok(views.html.index("You are logged in."))
}
}
答案 2 :(得分:2)
看看Deadbolt:https://github.com/schaloner/deadbolt-2。有详尽的例子和指南。
在我的Play 2项目中完美运作。
答案 3 :(得分:1)
您可以使用Filter
,它适用于应用程序中的每个请求。但是,您需要在Filter
中包含一些代码,以允许在没有有效会话的情况下访问某些URL,否则用户将无法首先登录。