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 ?
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
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.
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
Thanks for the answer.
Yes, using transient Host I was able to achieve this.