如何:JavaScript 中的 WSSE SOAP 请求(节点)



我需要从 Wix.com 平台上的节点服务器与soap:xml API进行通信。该 API 需要 Soap WSSE 身份验证。

我可以在 SoapUI 中向端点发送经过身份验证的请求,但是无法在 Wix 节点平台上成功执行此操作。

Wix只有一部分节点包可供安装,XMLHttpRequest在其环境中不可用。

我尝试过节点肥皂,但收到错误,表明该软件包可能在 Wix 节点平台上有问题。

我发现自己使用节点"请求"(https://www.npmjs.com/package/request)包,并尝试推出自己的解决方案来解决缺少的节点包和环境限制。

目前我可以向端点发送请求,但是我收到以下响应;

<?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>Access denied</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>n

这对我来说表明我没有正确进行身份验证。

正如我所提到的,我已经能够通过 SoapUI 成功发送请求并接收预期的响应。所以 API 正在运行,我怀疑是我的实现出了问题。老实说,我过去曾使用过 REST/JSON API,我已经很久没有使用 SOAP API 了,我记得当时我有很多痛苦!

我的请求代码

import request from 'request';
import {wsseHeaderAssoc} from 'backend/wsse';
export function getLocationID() {
let apiUsername = "username";
let apiPassword = "password";
let apiURL = "https://api.serviceprovider.com/wsdl";
// WSSE authentication header vars
    let wsse = wsseHeaderAssoc(apiUsername, apiPassword);
let wsseUsername = wsse["Username"];
let wssePasswordDigest = wsse["PasswordDigest"];
let wsseCreated = wsse["Created"];
let wsseNonce = wsse["Nonce"];
let xml =
`<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:masked:api">`+
`<soapenv:Header>`+
`<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">`+
`<wsse:UsernameToken wsu:Id="UsernameToken-19834957983507345987345987345">`+
`<wsse:Username>${wsseUsername}</wsse:Username>`+
`<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">${wssePasswordDigest}</wsse:Password>`+
`<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">${wsseNonce}</wsse:Nonce>`+
`<wsu:Created>${wsseCreated}</wsu:Created>`+
`</wsse:UsernameToken>`+
`</wsse:Security>`+
`</soapenv:Header>`+
`<soapenv:Body>`+
...
`</soapenv:Body>`+
`</soapenv:Envelope>`
var options = {
url: apiURL,
method: 'POST',
body: xml,
headers: {
'Content-Type':'text/xml;charset=utf-8',
'Accept-Encoding': 'gzip,deflate',
'Content-Length':xml.length,
'SOAPAction':"https://api.serviceprovider.com/wsdl/service",
'User-Agent':"Apache-HttpClient/4.1.1 (java 1.5)",
'Connection':"Keep-Alive"
}
};
let callback = (error, response, body) => {
if (!error && response.statusCode == 200) {
console.log('Raw result ', response);
// If you ever get this working, do some mad magic here
};
console.log('Error ', response);  
};
}

我正在使用 wsse-js (https://github.com/vrruiz/wsse-js/blob/master/wsse.js) 生成密码摘要、创建的日期时间戳和 Nonce 作为节点 wsse 包 (https://www.npmjs.com/package/wsse) 在 Wix 上不可用。我已经阅读了代码,根据我在其他地方阅读的内容,这看起来是一个很好的实现。

我做了一个小的补充,以在 assoc 数组中返回生成的详细信息;

export function wsseHeaderAssoc(Username, Password) {
var w = wsse(Password);
var wsseAssoc = [];
wsseAssoc["Username"] = Username;
wsseAssoc["PasswordDigest"] = w[2];
wsseAssoc["Created"] = w[1];
wsseAssoc["Nonce"] = w[0];
return wsseAssoc;
}

如前所述,我收到了以下回复;

<?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>Access denied</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>n

我期待一个有效的 SOAP XML 响应。

我使用了 SoapUI 中的原始 xml 结构和标头来构造它,一切看起来都很好,我真的不知道我哪里出错了。

我喜欢任何人都可以抛出的任何指针 - 我已经浪费了 2 天试图蛮力,我需要帮助。

您可以使用 soap 包中的WSSecurity方法。他们的自述文件中的一个例子:

var options = {
hasNonce: true,
actor: 'actor'
};
var wsSecurity = new soap.WSSecurity('username', 'password', options)
client.setSecurity(wsSecurity);

最新更新