e a
e a

Reputation: 103

SOAP-Request works with PHP but throws Syntax-Error with NodeJS

I'm using a given SOAP-API to request some stuff. That API is well documented but all examples are written in PHP, not my prefered language. All my implementation in PHP works, but now I want to implement and integrate it in my ExpressJS-Service. I'm using a popular NodeJS-SOAP-Library and exact the same request data. But the request to the API returns the following error message:

    <?xml version="1.0" encoding="UTF-8"?>\n
        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
        <SOAP-ENV:Body>
            <SOAP-ENV:Fault>
                <faultcode>SOAP-ENV:Client</faultcode><faultstring>session_lifetime_syntax_incorrect:w</faultstring><faultactor>KasAuth</faultactor>
            </SOAP-ENV:Fault>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>\n

The generated request body looks like this:

<?xml version="1.0" encoding="utf-8"?>
   <soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tns="https://kasserver.com/">
        <soap:Body>
            <tns:KasAuth><KasUser>[username]</KasUser>
            <KasAuthType>sha1</KasAuthType>
            <KasPassword>[password-hash]</KasPassword>
            <SessionLifeTime>600</SessionLifeTime>
            <SessionUpdateLifeTime>Y</SessionUpdateLifeTime>
            </tns:KasAuth>
        </soap:Body>
    </soap:Envelope>

My JavaScript-Code looks like this:

var soap = require('soap');
var sha1 = require('js-sha1');

var password = sha1('[password]');

var url = '[api-url].wsdl';
var args = {
    KasUser: '[username]',
    KasAuthType: 'sha1',
    KasPassword: password,
    SessionLifeTime: 600,
    SessionUpdateLifeTime: 'Y'
};

soap.createClient(url, function(err, client) {
    client.KasAuth(args, function(err, result) {
        console.log(result);
    });
});

My working PHP-Code looks like this:

...
$session_lifetime = 600;
$session_update_lifetime = 'Y';
...
try
    {
      $SoapLogon = new SoapClient('[api-url].wsdl');
      $CredentialToken = $SoapLogon->KasAuth(json_encode(array(
                            'KasUser' => $kas_user,
                            'KasAuthType' => 'sha1',
                            'KasPassword' => sha1($kas_pass),
                            'SessionLifeTime' => $session_lifetime,
                            'SessionUpdateLifeTime' => $session_update_lifetime
                            )));

      header('Content-Type: application/json');
      echo(json_encode(array('token' => $CredentialToken), JSON_PRETTY_PRINT));

    }

    // Fehler abfangen und ausgeben
    catch (SoapFault $fault)
    {
        trigger_error("Fehlernummer: {$fault->faultcode},
                        Fehlermeldung: {$fault->faultstring},
                        Verursacher: {$fault->faultactor},
                        Details: {$fault->detail}", E_USER_ERROR);
    }

The request body of my working PHP-Code:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:xmethodsKasApiAuthentication" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:KasAuth>
      <Params xsi:type="xsd:string">{"KasUser":[username],"KasAuthType":"sha1","KasPassword":[password-hash],"SessionLifeTime":600,"SessionUpdateLifeTime":"Y"}</Params>
    </ns1:KasAuth>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Login credetials are the same.

I tried to change the value for SessionLifeTime to 600.0 and '600'...

The API-Provider has no idea what could be wrong.

UPDATE: I see the request bodies are different, but I don't know how to change it in node-soap.

Upvotes: 0

Views: 190

Answers (1)

Roger Roelofs
Roger Roelofs

Reputation: 187

The biggest difference is that the php version turns all the params into a json string and stuffs it into the Params element while the js version encodes the js object into xml. I'd make the js side match with something like JSON.stringify(args)}.

Upvotes: 1

Related Questions