I have a login route that should transmit its input parameters as POST variables. I have defined my route like this:
POST /v1/accounts/login controllers.v1.Accounts.login(username: String, password: String)
and my Controller is like this:
object Accounts extends Controller {
def login(username: String, password: String) = Action {
Ok("Foo " + username)
}
}
When I test this route using Chromes Advance REST Client it only works for GET parameters and not if I send it as application/x-www-form-urlencoded
POST form data.
The Play Framework documentation never actually mentions POST parameters but neither does it say that it does not work.
I think it might get it to work if I create a Form and bind my request to that but that seems needlessly complex.
Is there really no way to bind POST parameters using the routes file?
Route = resolving params inside the URL = sending params via GET.
That means, that you are trying to send POST request by... GET params... where's the sense ?
James Roper explains that:
At routing time, Play hasn't yet consumed the request body, and so hasn't parsed the submitted form. - and you don't want it to either, because it's your action that decides how/whether the request body gets parsed, streamed, sent elsewhere, if Play did this at routing time, it would limit what you could do in an action.
From security point of view it's definitely bad idea to leave credentials in logs of every machine in the path of client.
Instead you should do it with common form handling way like described in base form documentation:
route:
POST /v1/accounts/login controllers.v1.Accounts.login
action:
val userForm = Form(
tuple(
"username" -> text,
"password" -> text
)
)
def login = Action { implicit request =>
val (username, password) = userForm.bindFromRequest.get
Ok("Hello " + username + ", you're trying to login with: " + password)
}