Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Check exist condition for Request Headers & Query Param's in JavaScript

Hi All, attached code is not working. It's going into if loop even query Param's not present in the request. Please suggest anyone knows.   

RakeshSudhagoni_1-1731304459120.png

 

Solved Solved
0 4 472
1 ACCEPTED SOLUTION

Glad to hear you resolved the issue using request.queryparams.count - nice work! 🎉

On your point about logging query parameters: while it's helpful to store them in a single variable, it's worth being cautious with this approach. Some query parameters, like access_token or api_key, might contain sensitive data or PII. Logging them directly could expose this information, which might lead to compliance and security issues.

Here’s an approach that handles this safely:

  1. Sensitive Data Masking:

    • You can define a sensitiveQueryParamNames variable in your proxy (e.g., "access_token,api_key") to specify parameters you don’t want logged. These are masked with ***.
    • The code also normalizes parameter names to lowercase, so it’s case-insensitive (access_token or Access_Token are treated the same).
  2. Handling Duplicate Parameters:

    • If multiple values are sent for the same parameter (e.g., param=value1&param=value2), it collects all the values and stores them as a comma-separated string in the log.

Here’s an example of how the code works:

 

var queryParamCount = context.getVariable("request.queryparams.count");
if (queryParamCount > 0) {
    var queryParamNamesString = context.getVariable("request.queryparams.names.string"); // Comma-separated string of query parameter names
    var sensitiveQueryParamNames = context.getVariable("sensitiveQueryParamNames") || "access_token,api_key"; // Comma-separated sensitive parameter names
    var sensitiveParams = sensitiveQueryParamNames.split(",").map(function (param) {
        return param.trim().toLowerCase(); // Normalize to lowercase for case-insensitive comparison
    });
    var queryParamObject = {};

    // Split the comma-separated list of parameter names
    var queryParamNamesArray = queryParamNamesString.split(",");
    for (var i = 0; i < queryParamNamesArray.length; i++) {
        var paramName = queryParamNamesArray[i].trim();
        var paramNameLower = paramName.toLowerCase(); // Normalize to lowercase

        if (sensitiveParams.includes(paramNameLower)) {
            // Mask sensitive parameter values
            queryParamObject[paramName] = "***";
        } else {
            // Collect all values for the parameter
            var paramValuesCount = context.getVariable("request.queryparam." + paramName + ".values.count");
            var paramValuesArray = [];
            for (var j = 1; j <= paramValuesCount; j++) {
                var value = context.getVariable("request.queryparam." + paramName + "." + j);
                paramValuesArray.push(value);
            }
            // Join multiple values into a single string
            queryParamObject[paramName] = paramValuesArray.join(",");
        }
    }

    context.setVariable("ProxyReqQueryParams", JSON.stringify(queryParamObject));
}

 

For a query string like:
param1=value1&param1=value2&ACCESS_TOKEN=12345, and with default sensitiveQueryParamNames, this would log: { "param1": "value1,value2", "ACCESS_TOKEN": "***" }

This way, you can log parameters safely while avoiding sensitive data exposure!

For more details on securing Apigee and best practices, you might find my blog helpful: Apigee Best Security Practices.

View solution in original post

4 REPLIES 4

Hi @RakeshSudhagoni,

That's because request.queryParams will never be undefined! Even if you don't pass queryparams in request to your proxy, Apigee still initialise request.queryParams as an object, just an empty one!

This means your if condition (typeof request.queryParams !== "undefined") will always evaluate to true, even when no query parameters are provided. That’s why the code is entering the if block.

But honestly, what is this code supposed to accomplish? It’s kinda weird, to be frank. You're creating a new object (queryParamObject) and copying over properties from request.queryParams one by one, even though request.queryParams itself is already an object with all the same data.

Why not just use request.queryParams directly? Unless there's some specific transformation or validation missing in the snippet, this looks unnecessary.

hi @nmarkevich ,

I tried to store al the query Param's in a single variable for the logging purpose. 

Why not just use request.queryParams directly?===> Here, It helps when the query name mentioned.

Any way I resolved the issue by using 'request.queryparams.count'

Thanks for response...

RakeshSudhagoni_0-1731319765043.png

 

Glad to hear you resolved the issue using request.queryparams.count - nice work! 🎉

On your point about logging query parameters: while it's helpful to store them in a single variable, it's worth being cautious with this approach. Some query parameters, like access_token or api_key, might contain sensitive data or PII. Logging them directly could expose this information, which might lead to compliance and security issues.

Here’s an approach that handles this safely:

  1. Sensitive Data Masking:

    • You can define a sensitiveQueryParamNames variable in your proxy (e.g., "access_token,api_key") to specify parameters you don’t want logged. These are masked with ***.
    • The code also normalizes parameter names to lowercase, so it’s case-insensitive (access_token or Access_Token are treated the same).
  2. Handling Duplicate Parameters:

    • If multiple values are sent for the same parameter (e.g., param=value1&param=value2), it collects all the values and stores them as a comma-separated string in the log.

Here’s an example of how the code works:

 

var queryParamCount = context.getVariable("request.queryparams.count");
if (queryParamCount > 0) {
    var queryParamNamesString = context.getVariable("request.queryparams.names.string"); // Comma-separated string of query parameter names
    var sensitiveQueryParamNames = context.getVariable("sensitiveQueryParamNames") || "access_token,api_key"; // Comma-separated sensitive parameter names
    var sensitiveParams = sensitiveQueryParamNames.split(",").map(function (param) {
        return param.trim().toLowerCase(); // Normalize to lowercase for case-insensitive comparison
    });
    var queryParamObject = {};

    // Split the comma-separated list of parameter names
    var queryParamNamesArray = queryParamNamesString.split(",");
    for (var i = 0; i < queryParamNamesArray.length; i++) {
        var paramName = queryParamNamesArray[i].trim();
        var paramNameLower = paramName.toLowerCase(); // Normalize to lowercase

        if (sensitiveParams.includes(paramNameLower)) {
            // Mask sensitive parameter values
            queryParamObject[paramName] = "***";
        } else {
            // Collect all values for the parameter
            var paramValuesCount = context.getVariable("request.queryparam." + paramName + ".values.count");
            var paramValuesArray = [];
            for (var j = 1; j <= paramValuesCount; j++) {
                var value = context.getVariable("request.queryparam." + paramName + "." + j);
                paramValuesArray.push(value);
            }
            // Join multiple values into a single string
            queryParamObject[paramName] = paramValuesArray.join(",");
        }
    }

    context.setVariable("ProxyReqQueryParams", JSON.stringify(queryParamObject));
}

 

For a query string like:
param1=value1&param1=value2&ACCESS_TOKEN=12345, and with default sensitiveQueryParamNames, this would log: { "param1": "value1,value2", "ACCESS_TOKEN": "***" }

This way, you can log parameters safely while avoiding sensitive data exposure!

For more details on securing Apigee and best practices, you might find my blog helpful: Apigee Best Security Practices.

Dear @nmarkevich ,

Thanks Alot, This code will makes my code strong.