vlad_o
vlad_o

Reputation: 657

Retrieve/Change url parameter in Action

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

  1. that I cannot retrieve the :id specified from the original call using ctx

  2. 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

Answers (1)

avik
avik

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:

SecurityAuthAction.java

public Promise<SimpleResult> call(Http.Context ctx) throws Throwable {

    if (authorisation token header is present in request) {
        return delegate.call(ctx);
    }

    return unauthorised();
}

Controller.java

@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

Related Questions