how to set headers using node-soap in node.js - node.js

I am trying to consume a wsdl service and found node-soap, but I cannot find how to set some headers.
Example :
header = {
"Username": "foo",
"Password" : "bar"
}
The reason I need this is because the wsdl I am trying to consume requires the username and password via the headers.
Thanks in advance

It may not be useful now however inorder to answering this question which is still open, here it goes.
You can make use of the method Client.addSoapHeader. As per the documentation
Client.addSoapHeader(soapHeader[, name, namespace, xmlns]) - add
soapHeader to soap:Header node
Options
soapHeader Object({rootName: {name: "value"}}) or strict xml-string
Optional parameters when first arg is object :
name Unknown parameter (it could just a empty string)
namespace prefix of xml namespace
xmlns URI
So you need to create an object and pass that to this method like:
var soapHeader = {
"Username": "foo",
"Password" : "bar"
};
client.addSoapHeader(soapHeader);

According with the documentation , for aggregate HTTP Headers, you can put headers, example code:
soap.createClient(url,
function (err, client) {
if(err){
console.log(err);
} else{
console.log(client.describe())
var soapHeaders = {
'Channel':'PB',
'RqUID':'1987'
}
client.addHttpHeader('<nameH1>', 'valueH1');
client.addHttpHeader('<nameH2>', 'valueH2');
//then, continue calling the soap operation
}

Reading through the README for node-soap, if what you're trying to do is not WS-Security (I have no idea because I stay far away from SOAP), then you're going to have to file an issue with the author, because I see no way to set custom headers according to the documentation.
If it is WS-Security, then follow the instructions on this part of the README.

soap = require('soap')
parseString = require('xml2js').parseString
soap.createClient('https://api.bingads.microsoft.com/Api/Advertiser/AdIntelligence/v9/AdIntelligenceService.svc?wsdl', function(err, client) {
var soapHeader = {
'AuthenticationToken': process.argv[2],
'DeveloperToken': process.argv[3],
'CustomerId': process.argv[4],
'CustomerAccountId': process.argv[5]
};
client.addSoapHeader(soapHeader);
client.SuggestKeywordsFromExistingKeywords({Keywords: ["Hello world"]}, function(err, result) {
console.log(result.body);
});
});
This won't work. The reply is invalid login credentials. The same credentials work fine with SOAPUI. So, the format of sending the login credentials mentioned in the other answers must be wrong.

This worked for me. The create client method needs the wsdl_header to retrieve the wsdl definition. Once it is created, you need to set the basic auth security.
var url = 'your WSDL url';
var auth = "Basic " + new Buffer("username" + ":" + "password").toString("base64");
soap.createClient( url,{ wsdl_headers: {Authorization: auth} }).then(
function(client){
client.setSecurity(new soap.BasicAuthSecurity('rflhconfort_ws', '6syqxje9'));
client.your_Method(args);
}

I had the same issue and i resolved it in the below is what worked for me
My wsdl with which i inserted data using SOAPUI Client(To see what are the fields required)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:yourUrn">
<soapenv:Header>
<urn:AuthenticationMethod>
<urn:userName>username</urn:userName>
<urn:password>password</urn:password>
</urn:AuthenticationMethod>
</soapenv:Header>
<soapenv:Body>
<urn:SoapFunctionToCall>
<urn:Field1>Text</urn:Field1>
<urn:Field2>Text</urn:Field2>
<urn:Field3>Text</urn:Field3>
<urn:Field14>Text</urn:Field4>
<urn:Field5>Text</urn:Field5>
<urn:Field6>Text</urn:Field6>
</urn:SoapFunctionToCall>
</soapenv:Body>
</soapenv:Envelope>
Below is the method i called in node
function createSoapEntry(){
let url = "your wsdl url"
var credentials = {
AuthenticationMethod:{
userName: "username",
password: "password"
}
}
let args = {
Field1:"Text",
Field2:"Text",
Field3:"Text",
Field4:"Text",
Field5:"Text",
Field6:"Text"
}
soap.createClient(url, function (err, client){
client.addSoapHeader(credentials)
client.SoapFunctionToCall(args, function (err, res) {
if (err) {
console.log("Error is ----->" + err)
} else {
console.log("Response is -----> " + res)
}
})
})
}

Related

npm soap with auth header

I am attempting to us the npm soap package to create a series of endpoints to a remote server that I can interface with through angular 4. I have read the documentation, but I am still unclear with regards to its usage. Below is the WSDL. How do I create a client that I can use to interface with the endpoint below? Here is the WSDL.
http://208.180.122.191:8081/niku/wsdl/Query/ts_pending_approvals?tenantId=clarity
My expectation is that I should get a response with the following:
var soap = require('soap');
var url = 'http://208.180.122.191:8081/niku/wsdl/Query/ts_pending_approvals?tenantId=clarity';
var args = {Username: "jdoe", Password: "*******"};
soap.createClient(url, function(err, client) {
client.Login(args, function(err, result) {
console.log(result);
});
});
When i call console.log(client.describe()), I get the following:
{ ts_pending_approvalsQueryService:
{ ts_pending_approvalsQueryService:
{ Query: [Object],
Login: [Object],
WrappedLogin: [Object],
Logout: [Object] } } }
However, when I call login and pass the username and password, i get undefined. using SoapUI, I was able to successfully complete the request, using the following. My question is how do I simulate this in node.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:quer="http://www.niku.com/xog/Query">
<soapenv:Header/>
<soapenv:Body>
<quer:Login>
<quer:Username>jdoe</quer:Username>
<quer:Password>******</quer:Password>
</quer:Login>
</soapenv:Body>
</soapenv:Envelope>
I was able to resolve this on my own by setting the endpoint, which gave me the expected response token: 6312078__98C024DA-25CF-441E-A47B-A84DDE2FF140
var soap = require('soap');
var url = 'http://208.180.122.191:8081/niku/wsdl/Query/ts_pending_approvals';
var args = {Username: "jdoe", Password: "*****"};
soap.createClient(url, function(err, client) {
client.setEndpoint("http://208.180.122.191:8081/niku/xog")
client.Login(args,(error,result)=>{
if (error) throw error;
console.log(result)
})
});
It is also worth noting that when you're utilizing the package and you have send additional parameters, you may also have to send headers, which map to a namespace specified in the WSDL, in addition to complex structures that require multiple parameters. I was able to figure this out after some trial and error. See working example below:
/////////////////////////////////////////////////////////////////////////////////////////////////////
// 1TS Open Timesheet
ppmRouter.get("/open_time_sheet",(req,res,next) => {
var resourceid = req.query.param_resourceid
var soap = require('soap');
var url = config.wsdlQueryPath + 'open_time_sheet';
var sheader = { Auth: {Username: config.xog_user, Password: config.password}}
var args = {
Query: {Code: "open_time_sheet"},
Filter: {
param_resourceid: resourceid
}
};
soap.createClient(url, function(err, client) {
client.addSoapHeader(sheader,"","tns","Auth");
client.setEndpoint(config.xog_url)
client.Query(args,(error,result)=>{
if (error) throw error;
console.log(result)
res.send(result)
})
});
})

Node soap, consume password protected WSDL

I'm trying to build a SOAP client with Node, I'm using "soap" package (https://www.npmjs.org/package/soap) trying to consume a user/password protected WSDL.
I can't find how to pass those credentials before creating the client by "soap.createClient", and of course, I can't retrieve the WSDL if I don't provide the right credentials.
I've tried doing:
soap.security.WSSecurity('user', 'pass');
and then calling "createClient" but to no avail.
Also, I've tried to do it with the node-soap-client, with this client I (apparently) can connect to the WSDL, but after that, I've no idea where to go (how to invoke methods).
What am I doing wrong?
Thanks for all your help!
Username and password credentials can be passed like this:
var soap = require('soap');
var url = 'your WSDL url';
var auth = "Basic " + new Buffer("your username" + ":" + "your password").toString("base64");
soap.createClient(url, { wsdl_headers: {Authorization: auth} }, function(err, client) {
});
(derived from https://github.com/vpulim/node-soap/issues/56, thank you Gabriel Lucena https://github.com/glucena)
If its password protected you also need to check the correct security mechanism. I spend a day trying to figure out that the service used NTLM security(it was a clients project and I only got username and password to access the wsdl). In that case, you would need to pass the correct wsdl_options object
var wsdl_options = {
ntlm: true,
username: "your username",
password: "your password",
domain: "domain",
workstation: "workstation"
}
soap.createClient(data.credentials[data.type], {
wsdl_options
},
function(err, client) {
console.log(client.describe());
});
Also, you would need to setSecurity on the client before using any service.
the link to complete explanation: https://codecalls.com/2020/05/17/using-soap-with-node-js/
when I added the auth to the headers I still had a problem. After reading the code and a number of articles I found this to work.
// or use local wsdl if security required
let url = 'http://service.asmx?wsdl'
let wsdl = 'wsdl.wsdl';
let soap = require('soap');
let util = require('util')
soap.createClient(wsdl, function(err, client) {
//don't forget to double slash the string or else the base64 will be incorrect
client.setSecurity(new soap.BasicAuthSecurity('admin\\userName', 'password'));
client.MethodFromWSDL(args, function (err, result) {
console.log(util.inspect(result,{depth: null}))
});
});
This worked for me, the API required the auth parameters as
<UserDetails xmlns="http://url/">';
<userName>{$Username}</userName>
<password>{$Password}</password>
<program>{$program}</program>
</UserDetails>
After lots of trial and error - this ended working
const soapHeader = {
UserDetails: {
userName: process.env.userName,
password: process.env.password,
program: process.env.program
}
}
...
soap.createClient(path, function (err, client) {
if (err) {
console.log('Error creating SOAP client: ' + err);
}
client.addSoapHeader(soapHeader, "", "tns", process.env.URN);
client[process.env.FUNCTION](sargs, function (err, result, rawResponse, soapHeader, rawRequest) {
if (err) {
console.log('Error call SOAP function ' + process.env.FUNCTION + ': ', err);
}
else {
console.log(result);
}
...

Setting Authorization in Node.js SOAP Client

I want to access a WSDL service through SOAP Client in Node.js. I used soap node module. But I can't able to find any documentation to set username and password. I'm not going to create SOAP server, I just want SOAPClient which is similar to PHP's SoapClient, using which I should able to access the WSDL service.
Update:
I had forked and customised the source to support this feature https://github.com/sincerekamal/node-soap
You can provide username and password like this:
var soap = require('soap');
var url = 'your WSDL url';
var auth = "Basic " + new Buffer("your username" + ":" + "your password").toString("base64");
soap.createClient(url, { wsdl_headers: {Authorization: auth} }, function(err, client) {
});
(derived from https://github.com/vpulim/node-soap/issues/56, thank you Gabriel Lucena https://github.com/glucena)
Another option to add basic authentication is using client.addHttpHeader. I tried both setSecurity and setting wsdl_headers but neither worked for me when authenticating to Cisco CUCM AXL.
Here is what worked for me:
var soap = require('soap');
var url = 'AXLAPI.wsdl'; // Download this file and xsd files from cucm admin page
var auth = "Basic " + new Buffer("your username" + ":" + "your password").toString("base64");
soap.createClient(url,function(err,client){
client.addHttpHeader('Authorization',auth);
});
Just to share what I've read from https://github.com/vpulim/node-soap:
var soap = require('soap');
var url = 'your WSDL url';
soap.createClient(url, function(err, client) {
client.setSecurity(new soap.BasicAuthSecurity('your username','your password'));
});
You need to set the username and password by passing the authorisation to the wsdl_headers object e.g
var auth = "Basic " + new Buffer('username' + ':' + 'password').toString("base64");
var client = Soap.createClient('wsdlUrl', { wsdl_headers: { Authorization: auth } }, (err, client) => {
if (err) {
throw err;
} else {
client.yourMethod();
}
});
A small tweak to the existing answers: you can use your security object to create the header for the WSDL request too, e.g.
const security = new soap.BasicAuthSecurity(username, password);
const wsdl_headers = {};
security.addHeaders(wsdl_headers);
soap.createClientAsync(url, { wsdl_headers }).then((err, client) => {
client.setSecurity(security);
// etc.
});
Or if you're using something more complicated than BasicAuthSecurity you may also need to set wsdl_options from the security object, e.g.
const security = new soap.NTLMSecurity(username, password, domain, workstation);
const wsdl_headers = {}, wsdl_options = {};
security.addHeaders(wsdl_headers);
security.addOptions(wsdl_options);
soap.createClientAsync(url, { wsdl_headers, wsdl_options }).then((err, client) => {
client.setSecurity(security);
// etc.
});

Does the Gmail API support JWT?

I want to access the Gmail API using NodeJS.
I'm using a server-to-server approach (see this) but when I execute the code below, I get a backEndError, code 500 from the Google API.
Any ideas?
var authClient = new google.auth.JWT(
'email',
'key.pem',
// Contents of private_key.pem if you want to load the pem file yourself
// (do not use the path parameter above if using this param)
'key',
// Scopes can be specified either as an array or as a single, space-delimited string
['https://www.googleapis.com/auth/gmail.readonly']
);
authClient.authorize(function(err, tokens) {
if (err)
console.log(err);
gmail.users.messages.list({ userId: 'me', auth: authClient }, function(err, resp) {
// handle err and response
if (err) {
console.log(err);
});
Yes, I have the same problem. If I use the scope "https://mail.google.com", I get
403
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
And if I use the scope "https://mail.google.com/" (notice the / at the end), I get
403
'Forbidden'
It seems to be related to using JWT and service account.

Inserting Google Analytics Content Experiments using the Node.JS Client Library

I'm trying to configure a content experiment using the Node.js Client Library, and have not been able to work out the syntax. Where do I put the body (an Experiment resource) as described here?
https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtExperimentsGuide#insert
This code, for listing existing experiments, works as expected:
var listExperiments = function(){
googleapis
.discover('analytics', 'v3')
.execute(function(err, client) {
var request = client
.analytics.management.experiments.list({
accountId : accountId,
webPropertyId : webPropertyId,
profileId : profileId
})
.withApiKey(browserAPIKey)
.withAuthClient(oauth2Client)
request.execute(function(err,result){
if (err){
console.log(err);
res.send(402);
} else {
console.log(result);
res.send(200);
}
});
});
}
However, when I try to insert a new experiment thusly, I receive a "Field resource is required" error.
var body = {
"name": "myExperimentName",
"status": "READY_TO_RUN",
"objectiveMetric":"ga:bounces",
"variations": [
{ "name": "text1", "url":"http://www.asite.net", "status":"ACTIVE" },
{ "name": "text2", "url":"http://www.asite.net", "status":"ACTIVE" }
]
};
var insertExperiment = function(){
googleapis
.discover('analytics', 'v3')
.execute(function(err, client) {
var request = client
.analytics.management.experiments.insert({
accountId : accountId,
webPropertyId : webPropertyId,
profileId : profileId,
resource : body
})
.withApiKey(browserAPIKey)
.withAuthClient(oauth2Client)
request.execute(function(err,result){
if (err){
console.log(err);
res.send(402);
} else {
console.log(result);
res.send(200);
}
});
});
}
I've tried a few configurations. Management API writes are in limited beta, but I have beta access, so that's not the problem. I've tried inserting the new experiment information directly into the insert() object, calling the experiment info object "body : body " instead of "resource : body", JSON.stringifying the body, and a few other configurations. No luck.
Any help would be great!
I'm aware of this answer, but it uses the Javascript Client Library and makes RESTful requests, whereas I'd like to use the Node Library.
EDIT: Thanks to Burcu Dogan at Google. Here's the correct syntax:
.analytics.management.experiments.insert({
accountId : accountId,
webPropertyId : webPropertyId,
profileId : profileId
}, body)

Resources