简体   繁体   中英

Scala Play framework rest api add token from request to response

I'm trying to make all my rest api endpoints return the token with which the user used to make the request (already exists in all request). This is how my basic endpoint looks like:

def getAll(meta: MetaData): Action[AnyContent] = deadbolt.Restrict(role)(parse.default) { 
    implicit request => myService.getAll(meta).map(result => {
        val results: Seq[Resp] = result._2.map(res => Mapper(res))
        Ok(Json.toJson(MyListResponse.apply(meta, result._1, results)))
    })
}

How can I add to this my response the token's information received from in the request? Thanks!

As you described in comment section you need to get token from query parameter and add it response header. Let's suppose that this token is optional, hence might be absent, so this can be achieved something like:

implicit request => myService.getAll(meta).map { result => 
   // Fetch optional token as query parameter. `token_parameter` - parameter key
   val requestToken = request.queryString.get("token_parameter").flatMap(_.headOption)
   val results: Seq[Resp] = result._2.map(res => Mapper(res))
   val body = Json.toJson(MyListResponse.apply(meta, result._1, results))

   // Add token to header if it is present
   requestToken.fold(Ok(body))(token => Ok(body).withHeaders("token_header" -> token))
}

Update

In order to apply this logic to ALL the routes, you can use Play Filters feature. Please, see doc for more details: https://www.playframework.com/documentation/latest/ScalaHttpFilters

What you need to do:

1) Implement your own Play Filter . It would look something like next:

import javax.inject.Inject
import akka.stream.Materializer
import play.api.mvc._
import scala.concurrent.ExecutionContext
import scala.concurrent.Future

class TokenFilter @Inject() (implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
      def apply(nextFilter: RequestHeader => Future[Result])
               (requestHeader: RequestHeader): Future[Result] = {
            nextFilter(requestHeader).map { result =>
                val requestToken = requestHeader.queryString.get("token_parameter").flatMap(_.headOption)
                requestToken.fold(result )(token => result.withHeaders("token_header" -> token))
            }
    }
}

2) Wire filter to rest of application. For instance, via adding next config in application.conf

play.http.filters += com.yourcomany.TokenFilter

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM