我正在使用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"
)
)
}
}
答案 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)
}
}
}
这个特性基本上定义了两种方法:
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”调用