Reputation: 657
I make a call from my frontend to the userPrivateProfile controller.The route is /api/user/private/:id so let's say I make a call at /api/user/private/65. Before I excecute the controller the request is intecepted by SecurityAuthAction where I make sure that the request headers have the token and if that's the case I want to change the :id to something different.
Controller.java
@With(SecurityAuthAction.class)
public Result userPrivateProfile(Long id) {
//LOGIC
}
SecurityAuthAction.java
public Promise<SimpleResult> call(Http.Context ctx) throws Throwable {
String[] authTokenHeaderValues = ctx.request().headers()
.get(AUTH_TOKEN_HEADER);
if ((authTokenHeaderValues != null) && (authTokenHeaderValues.length == 1) && (authTokenHeaderValues[0] != null)) {
Long userId = sessionService
.findUserByToken(authTokenHeaderValues[0]);
ctx.args.put("id",userId.toString());
return delegate.call(ctx);
}
My problems are
that I cannot retrieve the :id specified from the original call using ctx
Since I cannot find where the request parameter is I cannot change it as well
I tried iterating through the ctx.args Map but I didn't find something there.The output is:
ROUTE_VERB ROUTE_
ACTION_METHOD
ROUTE_CONTROLLER
ROUTE_COMMENTS
ROUTE_PATTERN
GET
userPrivateProfile
controllers.Controller
/api/user/private/$id<[^/]+>
Thanx for your help :)
Upvotes: 2
Views: 345
Reputation: 2708
Unfortunately the Play Framework (certainly in version 2.1) does not give you easy access to URL query parameters when performing action composition. This discussion on the Play Google group may be of interest to you. One workaround mentioned there is to parse the URL in SecurityAuthAction
to get the value of the id
query parameter. However this is a little messy, and doesn't help you with the next part of your problem, which is changing the id before it gets to the downstream action.
Changing the details of the request as it's being handled by the server seems uncommon and wrong to me. Typically if you wanted to change what a client is requesting, you'd issue a HTTP 303 response redirecting them to the URL you want them to go to. But this doesn't feel like a situation for redirection. What I reckon you should do is just push your call to sessionService
down to your main controller class:
public Promise<SimpleResult> call(Http.Context ctx) throws Throwable {
if (authorisation token header is present in request) {
return delegate.call(ctx);
}
return unauthorised();
}
@With(SecurityAuthAction.class)
public Result userPrivateProfile(Long id) {
// We've already established that an auth token header is present in the request
final String authToken = ctx.request().headers().get(AUTH_TOKEN_HEADER)[0];
final Long userId = sessionService.findUserByToken(authToken);
// TODO: Proceed...
}
If userId
is something that you need all over your application, then it might be a candidate for inclusion in your application's cookie.
Upvotes: 1