播放2.0传递路线值到动作

时间:2012-12-13 03:35:30

标签: scala playframework-2.0

我正在使用Scala&播放2.0

我有一个URL:

/ v1 / people / search / MTIyOjg3YjYzNmU1YTk5MDdkYjY2MzAyODZiM2RkNTMzYzYw

在我的路径文件中:

POST / v1 / people / search /:authToken controllers.v1.Application.searchPeople(authToken:String)

我要做的是创建一个安全的特性并采取:aythToken并通过在我的函数/方法调用中替换它的自定义Action进行验证:

将动作设为CustomAuthAction

def searchPeople(authToken:String)= Action {implicit request => }

这样我就可以拒绝基于已解析的请求:authToken而不将此值设置为cookie,我已经知道如何做到这一点。

那么我怎么能把已经通过的游戏:authToken带到自定义动作?

由于


这是我的解决方案:

case class CheckSessionRequest(val user: User, request: Request[AnyContent]) extends   WrappedRequest(request)

def RequireAuthToken(f: CheckSessionRequest => Result): Action[AnyContent] = {
Action { request =>
UserValidation.findUserByAuthToken(StringUtil.getAuthTokenFromURL(request.toString)).map     { user =>
f(CheckSessionRequest(user, request))
}.getOrElse( // STRANGE ERROR
Ok(Json.generate(StatusHandler("failed","Unknown Login Error","{}"))).withHeaders(
CONTENT_TYPE -> "application/json"
) 
)
}
}

2 个答案:

答案 0 :(得分:2)

让我引用Play文档:

  

Play应用程序收到的大多数请求都是由   动作。

     

play.api.mvc.Action基本上是一个(play.api.mvc.Request =>   play.api.mvc.Result)处理请求并生成一个   结果发送给客户。

如果您查看Action Composition,它会清楚地向您解释如何基本创建CustomAction:

def LoggingAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
  Action { request =>
    Logger.info("Calling action")
    f(request)
  }
}

我做了类似的工作,这就是它看起来的样子,它有点复杂但很有趣

trait SecuredController[UserModel<:ValidableEmail] {

  type LoggedRequestHandler  =  UserModel =>Request[AnyContent] => Result

  def loggedUser(implicit request:Request[_]):Option[UserModel]

  def WithAuthenticatedUser( onUserAuthenticated: => LoggedRequestHandler,
                             onUserAuthenticatedButEmailNotValidated: LoggedRequestHandler,
                             onUnauthenticated: Request[AnyContent]=>Result) = {
    Action{
     implicit request =>
        loggedUser match{
          case Some(user) if (user.emailValidated) => onUserAuthenticated(user)(request)
          case Some(user) if(!user.emailValidated) => onUserAuthenticatedButEmailNotValidated(user)(request)
          case None => onUserNotLogged(request)
        }
    }
  }

这个特性基本上定义了两种方法:

  • 能够确定是否有当前登录用户的人 请求(通常使用会话)
  • 基本上创建一个具有三种可能结果的Action的一个:
    • onUserAuthenticated,以防有已验证电子邮件的已登录用户
    • onUserAuthenticatedButEmailNotValidated如果有记录但电子邮件未经过验证
    • onUserNotLogged如果已记录但电子邮件未经过验证

LoggedRequestHandler只是一个函数的类型别名,它接受我的用户UserModel并创建一个函数Request =&gt;结果

一旦你有了这个,你基本上可以写下面的

object EmployeeController extends SecuredController[Employee]{

    def loggedUser(implicit request:Request[_]):Option[Employee]

    def ViewPay = WithAuthenticatedUser{
       ShowPay, 
       ShowEmailNotValidated,
       ShowUserNotLogged        
    }

    def ShowPay(employee:Employee): Request[AnyContent] => Result = {

    }
    def ShowEmailNotValidated(employee:Employee): Request[AnyContent] => Result = {

    }

    def ShowUserNotLogged: Request[AnyContent] => Result = {

    }



}

答案 1 :(得分:1)

这是我提出的解决方案,效果很好。

case class CheckSessionRequest(val user: User, request: Request[AnyContent]) extends   WrappedRequest(request)

def RequireAuthToken(f: CheckSessionRequest => Result): Action[AnyContent] = {
    Action { request =>
     UserValidation.findUserByAuthToken(StringUtil.getAuthTokenFromURL(request.toString)).map     { user =>
      f(CheckSessionRequest(user, request))
     }.getOrElse( // STRANGE ERROR
      Ok(Json.generate(StatusHandler("failed","Unknown Login Error","{}"))).withHeaders(
       CONTENT_TYPE -> "application/json"
      ) 
    )
  }
}

然后用RequireAuthToken

替换你的“Action”调用