scala – EssentialAction:如何在不解析请求的情况下获取请求的
发布时间:2020-12-16 10:00:03 所属栏目:安全 来源:网络整理
导读:鉴于以下EssentialAction …… object MyController extends Controller { ... def HasToken(action: Token = EssentialAction) = EssentialAction { request = ... // this doesn't compile val body = request.body match { case json: JsValue = json.toS
鉴于以下EssentialAction ……
object MyController extends Controller { ... def HasToken(action: Token => EssentialAction) = EssentialAction { request => ... // this doesn't compile val body = request.body match { case json: JsValue => json.toString case _ => "" } // calculate hash with body content here ... } // here is an authenticated action def getUser(userId: Strign) = HasToken { token => Action(parse.json) { request => request.body.validate[User] match { ... } } } } …如何在不解析请求的情况下获取请求的正文? 我不想要,而且我不需要在HasToken中解析请求体,因为将在操作getUser中解析正文.我只需要身体的原始内容来计算哈希值. HasToken中的代码无法编译,因为请求的类型为RequestHeader,而我需要一个Request,它定义了body. 解决方法
这对你有用吗?
object MyController extends Controller { // Your HasToken Action def Authenticate(action: Token => EssentialAction) = EssentialAction { requestHeader => // ... execute logic to verify authenticity using requestHeader } // Your action to validate tampering of request body and validity of JSON def Validate[A](action: Token => Request[A]) = Action(parse.json) { request => val body = request.body body match { case json: JsValue => json.toString case _ => "" } // calculate hash with body content here body.validate[User] match { // ... } } def getUser(userId: Strign) = Authenticate { token => Validate { user => //.... Continue } } } >身份验证仅使用RequestHeader 编辑: 问题1:我不想验证Validate中的正文…因为我需要一个可以在任何地方使用的通用验证机制,无论内容类型如何(例如用户,消息等). 如何添加另一个类型参数(以使其成为通用): def Validate[A,B](action: Token => Request[A])(implicit reads: Reads[B]) = Action(parse.json) { request => // ... } 问题2:此外,如果令牌验证失败,则不必处理正文(这在文件上载的情况下很重要,当且仅当验证成功时才必须执行).在我看来,最好的选择是在Validate中读取正文的原始内容. 这很容易实现: def Validate[A,B](action: Token => Request[A])(implicit reads: Reads[B]) = Action(parse.json) { request => val body = request.body body match { case json: JsValue => json.toString case _ => "" } // calculate hash with body content here and figure out if the body is tampered if (bodyIsNotTampered) { body.validate[B] match { // ... } } else { // log and return Future.successful(BadRequest) } } 编辑3:完整解决方案: import play.api.libs.json.{Json,JsValue,Format} object CompilationUtils { class Token case class User(name: String) implicit val UserFormat = Json.format[User] def authenticate = new Token // authentication logic def isTampered(body: JsValue) = { val bodyAsStr: String = Json.stringify(body) // calculate hash with body content here false } } object MyController extends Controller { import CompilationUtils._ // Your HasToken Action def Authenticate(action: Token => EssentialAction) = EssentialAction { requestHeader => action(authenticate)(requestHeader) // your execute logic to verify authenticity using requestHeader } // Your action to validate tampering of request body and validity of JSON def Validate[A,B](request: Request[A])(implicit formatA: Format[A],formatB: Format[B]): Either[Result,B] = { val body = request.body val bodyAsJsValue = Json.toJson(body) if (!isTampered(bodyAsJsValue)) { bodyAsJsValue.validate[B].fold( valid = res => Right(res),invalid = err => Left(BadRequest(err.toString)) ) } else { Left(BadRequest) // Request Tampered } } def getUser(userId: String) = Authenticate { token => Action(parse.json) { request => Validate(request).fold( badReq => badReq,user => // continue... Ok("") ) } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |