In the following Controller
, Authenticated
extracts the token from the request headers and invokes a given action if and only if the token is valid (the code has been simplified for clarity):
object MyController extends Controller {
def Authenticated(action: Token => EssentialAction) = EssentialAction { requestHeader =>
val jwt = requestHeader.headers.get(HeaderNames.AUTHORIZATION) match {
case Some(header) => s"""$AuthScheme (.*)""".r.unapplySeq(header).map(_.head.trim)
case _ => requestHeader.getQueryString("auth").map(UriEncoding.decodePath(_, SC.US_ASCII.name))
}
jwt match {
case Some(t) if t.isValid =>
val token: Token = authService.token(t)
action(token)(requestHeader)
case _ => Done(Unauthorized.withHeaders(HeaderNames.WWW_AUTHENTICATE -> AuthScheme))
}
}
def getUser(userId: String) = Authenticated { token =>
Action.async { request =>
userService.find(userId).map {
case Some(user) => Ok(Json.obj("user" -> user.asJson)).withHeaders(
"token" -> authService.renew(token).asJson.toString
)
case _ => NotFound
}
}
}
}
The token returned by authService.token(t)
is a JWT (JSON Web Token) and it can be used only once... so I need to return a new token after each request. The idea would be to put the new token in the response headers. That said, is there a way to add the token
header to every response without having to invoke withHeader
in each action?
Simply you can create a Filter and in Global.scala add WithFilters class.
Here is a Filter sample for logging so you could change it easily to satisfy your needs.