SOAP API 调用 - 如何插入令牌

SOAP API call - How to insert Token

我正在调用 returns XML 的 SOAP API 并收到以下错误

错误-

    title>401 - Unauthorized: Access is denied due to invalid credentials.</title>

我已经使用了我可以在其他 SO 查询、SOAP 信息和我的特定调用文档中找到的信息,这是我到目前为止为它整理的代码

String soap = 
  '''<?xml version="1.0"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
 xmlns:ns1="http://thalesgroup.com/RTTI/2014-02-20/ldb/" 
 xmlns:ns2="http://thalesgroup.com/RTTI/2017-10-01/ldb/GetDepartureBoard">
  <SOAP-ENV:Header>
    <ns2:AccessToken>
      <ns2:TokenValue>my_token</ns2:TokenValue>
    </ns2:AccessToken>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:GetDepartureBoardRequest>
      <ns1:numRows>10</ns1:numRows>
      <ns1:crs>MAN</ns1:crs>
    </ns1:GetDepartureBoardRequest>
  </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>''';

  // Send the POST request, with full SOAP envelope as the request body.
 http.Response response = await http.post(Uri.parse(
  'https://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx'),
  headers: {
    'Content-Type': 'text/xml; charset=utf-8',
    'SOAPAction': 'http://thalesgroup.com/RTTI/2017-10-01/ldb/GetDepartureBoard'
  },
  body: soap
);


var rawXmlResponse = response.body;


final parsedXml = XmlDocument.parse (rawXmlResponse);
print(parsedXml);


}

API 的提供者在其文档中声明

    This token shall be passed as a SOAP Header value.

我包含在 body 中是否足够,或者我如何在部分中引用它...

headers: {
    'Content-Type': 'text/xml; charset=utf-8',
    'SOAPAction': 'http://thalesgroup.com/RTTI/2017-10-01/ldb/GetDepartureBoard'

这是一个例子 - https://wiki.openraildata.com/index.php/GetDepBoardWithDetails

数据来自 - https://realtime.nationalrail.co.uk/OpenLDBWS/

谢谢

更新通话

String soap = 
  '''
<SOAP-ENV:Envelope 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns1="http://thalesgroup.com/RTTI/2017-10-01/ldb/"
xmlns:ns2="http://thalesgroup.com/RTTI/2013-11-28/Token/ns2es">
 <SOAP-ENV:Header>
   <ns2:AccessToken>
     <ns2:TokenValue>my_token</ns2:TokenValue>
   </ns2:AccessToken>
 </SOAP-ENV:Header>
 <SOAP-ENV:Body>
   <ns1:GetDepartureBoardRequest>
     <ns1:numRows>10</ns1:numRows>
     <ns1:crs>MAN</ns1:crs>
   </ns1:GetDepartureBoardRequest>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>''';
 

  // Send the POST request, with full SOAP envelope as the request body.
 http.Response response = await http.post(Uri.parse(
  'https://realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01'),
  headers: {
    'SOAPAction': 'http://thalesgroup.com/RTTI/2017-10-01/ldb/GetDepartureBoard'
  },
  body: soap
);

更新回复

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://thalesgroup.com/RTTI/2017-10-01/ldb/" targetNamespace="http://thalesgroup.com/RTTI/2017-10-01/ldb/">
<wsdl:import namespace="http://thalesgroup.com/RTTI/2017-10-01/ldb/" location="rtti_2017-10-01_ldb.wsdl"/>
<wsdl:service name="ldb">
  <wsdl:port name="LDBServiceSoap" binding="tns:LDBServiceSoap">
    <soap:address location="https://realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx"/>
  </wsdl:port>
  <wsdl:port name="LDBServiceSoap12" binding="tns:LDBServiceSoap12">
    <soap12:address location="https://realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx"/>
  </wsdl:port>
</wsdl:service>
</wsdl:definitions>

这是哪个网页 - https://realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01

正确的 SOAP 消息应如下所示:

<SOAP-ENV:Envelope 
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns1="http://thalesgroup.com/RTTI/2017-10-01/ldb/"
xmlns:ns2="http://thalesgroup.com/RTTI/2013-11-28/Token/ns2es">
 <SOAP-ENV:Header>
   <ns2:AccessToken>
     <ns2:TokenValue>my_token</ns2:TokenValue>
   </ns2:AccessToken>
 </SOAP-ENV:Header>
 <SOAP-ENV:Body>
   <ns1:GetDepartureBoardRequest>
     <ns1:numRows>10</ns1:numRows>
     <ns1:crs>MAN</ns1:crs>
   </ns1:GetDepartureBoardRequest>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

注意 ns1ns2 命名空间。

根据您发布的文档,要使用的 WSDL 位于 https://realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01,并且基于该 WSDL 使用的名称空间是我发布的消息中的名称空间。您使用的示例看起来更旧;该页面于 2016 年 10 月 18 日在 20:51 发布,但 WSDL 上的版本参数显示为 2017)。

在编写代码之前,我建议您将 WSDL link 提供给 SoapUI 并进行一些测试调用,直到调用与 SoapUI 一起工作。然后您可以编写代码来复制 SoapUI 发出的请求。

显然,您还需要一个有效的令牌才能发送到服务。由于它用于访问,如果您没有发送有效消息,那么您显然将无法访问,即使您的 SOAP 消息已正确构建。

All licensed users will be issued with a token to access public web services. This token shall be passed as a SOAP Header value. The service will reject all requests with no token or an incorrect token code.

您是授权用户吗?您是否从他们那里收到了要在通话中使用的令牌?

编辑:在问题中添加了额外的细节之后。

您没有将 SOAP 消息发送到正确的端点。你需要做一个 POST 到 https://realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx 而不是 https://realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01.

https://realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01 URL 只是给你服务的 WSDL,WSDL 里面的 SOAP 地址告诉你服务端点实际在哪里:

<soap:address location="https://realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx"/>

您可能还想阅读这些内容:

关于如何获取服务及其端点的 WSDL,通常约定是使用 POST endpoint 调用服务,并使用 GET endpoint?wsdl 获取 WSDL。但这只是一个惯例。这两件事可以彼此分开,在你的情况下它们是。您在一个端点上获取 WSDL,而调用在另一个端点上完成。这就是为什么您需要使用不同的端点。