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>
注意 ns1
和 ns2
命名空间。
根据您发布的文档,要使用的 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"/>
您可能还想阅读这些内容:
- Cannot show the endpoint list when calling link without ?wsdl, but still can call the SOAP web service?
- The WSDL is not the SOAP web service
关于如何获取服务及其端点的 WSDL,通常约定是使用 POST endpoint
调用服务,并使用 GET endpoint?wsdl
获取 WSDL。但这只是一个惯例。这两件事可以彼此分开,在你的情况下它们是。您在一个端点上获取 WSDL,而调用在另一个端点上完成。这就是为什么您需要使用不同的端点。
我正在调用 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>
注意 ns1
和 ns2
命名空间。
根据您发布的文档,要使用的 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"/>
您可能还想阅读这些内容:
- Cannot show the endpoint list when calling link without ?wsdl, but still can call the SOAP web service?
- The WSDL is not the SOAP web service
关于如何获取服务及其端点的 WSDL,通常约定是使用 POST endpoint
调用服务,并使用 GET endpoint?wsdl
获取 WSDL。但这只是一个惯例。这两件事可以彼此分开,在你的情况下它们是。您在一个端点上获取 WSDL,而调用在另一个端点上完成。这就是为什么您需要使用不同的端点。