VMware Cloud Community
rohi38rtt
Contributor
Contributor
Jump to solution

VRO REST OPERATION SUPPORTING application/x-www-form-urlencoded

Use-Case

----------------------------------

I need to use Guardium REST API to get Login Token. The API has body uses Content-Type - application/x-www-form-urlencoded.

I have create a REST Operation for the same with same content type.

Issue

---------------------------------

The API works fine in Postman and gives the exact result but it's not working in vRO

I have used the below code to test the same:

var inParamtersValues = [];

var headerParams = [];

var acceptHeadersValue = "";

content = "client_id=oauth_client3&grant_type=password&client_secret=secret&username=xxxxxxx&password=xxxxxx"

var request = restOperation.createRequest(inParamtersValues, content);

//set the request content type]

if (System.getModule("com.vmware.library.http-rest.configuration").hasHttpMethodHasBodyPayload(request.getMethod())) {

//System.log("Setting defaut content type to:  " + defaultContentType );

request.contentType = defaultContentType;

}

var headerParamNames = restOperation.getHeaderParameters();

if (acceptHeaders && acceptHeaders.length > 0) {

    for (var k in acceptHeaders) {

acceptHeadersValue = acceptHeadersValue +  acceptHeaders[k] + ",";

}

var acceptHeadersStringSize = acceptHeadersValue.length -1 ;

acceptHeadersValue = acceptHeadersValue.substring(0, acceptHeadersStringSize);

// the accept header value shall start with lower-case letter "a" to override the default setted accept header type 

    request.setHeader("accept", acceptHeadersValue);

}

for (var k in headerParamNames) {

  System.log(" SET headers: " + headerParamNames[k] + " : " + headerParams[k]);

  request.setHeader(headerParamNames[k], headerParams[k]);

}

/request.setHeader("X-Requested-With", "message/http");

var response = request.execute();

System.log("Response: " + response);

contentAsString = response.contentAsString;

System.log("Content as string: " + contentAsString);

Response

--------------------------------

{"error":"unauthorized", "error_description":"Bad Credentials"}

Is anything wrong with the code ?

0 Kudos
1 Solution

Accepted Solutions
aamarques
Enthusiast
Enthusiast
Jump to solution

I have a case that I need to get credentials and it does use x-www-form-urlencoded content-type. The trick is to url encode the JSON parameters and set the content type. I think you can adapt to make it work for you.

function xwwwfurlenc(srcjson){

    if(typeof srcjson !== "object")

      if(typeof console !== "undefined"){

        System.log("\"srcjson\" is not a JSON object");

        return null;

      }

    u = encodeURIComponent;

    var urljson = "";

    var keys = Object.keys(srcjson);

    for(var i=0; i <keys.length; i++){

        urljson += u(keys[i]) + "=" + u(srcjson[keys[i]]);

        if(i < (keys.length-1))urljson+="&";

    }

    return urljson;

}

Here I defined the payload as an object:

var payload = {

    "grant_type": "client_credentials",

    "client_id": ins["client_id"],

    "client_secret": ins["client_secret"],

    "resource": "https://url resource code"

};

Then finally execute the request, note that on createRequest I call the xwwwfurlenc (wich is an action in a module but I just put that as a function for sake of simplicity:

var request = transientHost.createRequest("POST", "",xwwwfurlenc(payload));

request.contentType = "application/x-www-form-urlencoded";

request.setHeader("Accept", "application/json");

var response = request.execute();

var res = JSON.parse(response.contentAsString);

if(!res.access_token) {

throw "No Access Token Found";

}

token = res.access_token

Let me know if that helps Smiley Happy

View solution in original post

3 Replies
stevedrummond
Hot Shot
Hot Shot
Jump to solution

You have this line:

request.contentType = defaultContentType;

but I don't see anywhere that you have defined defaultContentType? If you defined it on your REST operation you've now just overridden it to be nothing.

Also ensure your body is URI encoded.

0 Kudos
aamarques
Enthusiast
Enthusiast
Jump to solution

I have a case that I need to get credentials and it does use x-www-form-urlencoded content-type. The trick is to url encode the JSON parameters and set the content type. I think you can adapt to make it work for you.

function xwwwfurlenc(srcjson){

    if(typeof srcjson !== "object")

      if(typeof console !== "undefined"){

        System.log("\"srcjson\" is not a JSON object");

        return null;

      }

    u = encodeURIComponent;

    var urljson = "";

    var keys = Object.keys(srcjson);

    for(var i=0; i <keys.length; i++){

        urljson += u(keys[i]) + "=" + u(srcjson[keys[i]]);

        if(i < (keys.length-1))urljson+="&";

    }

    return urljson;

}

Here I defined the payload as an object:

var payload = {

    "grant_type": "client_credentials",

    "client_id": ins["client_id"],

    "client_secret": ins["client_secret"],

    "resource": "https://url resource code"

};

Then finally execute the request, note that on createRequest I call the xwwwfurlenc (wich is an action in a module but I just put that as a function for sake of simplicity:

var request = transientHost.createRequest("POST", "",xwwwfurlenc(payload));

request.contentType = "application/x-www-form-urlencoded";

request.setHeader("Accept", "application/json");

var response = request.execute();

var res = JSON.parse(response.contentAsString);

if(!res.access_token) {

throw "No Access Token Found";

}

token = res.access_token

Let me know if that helps Smiley Happy

rohi38rtt
Contributor
Contributor
Jump to solution

Thanks for the answer.

Yes, using transient Host I was able to achieve this.

0 Kudos