首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用Delphi/Indy调用

使用Delphi/Indy调用
EN

Stack Overflow用户
提问于 2014-05-09 12:53:52
回答 1查看 2K关注 0票数 2

我正在开发一个简单的应用程序来与Amazon“交谈”。因为这里有很多现有的代码,所以我需要在Delphi 2010中使用Indy 10 (10.5.5)组件完成这一任务,过去我已经成功地将这些组件与许多其他API集成在一起。然而,Amazon似乎对最小的细节非常敏感,以至于我所有的调用都被已经臭名昭著的"SignatureDoesNotMatch“错误消息所拒绝。

以下是我到目前为止所取得的成就:

1)我的应用程序将组装一个请求,用HMAC- the 256(使用OpenSSL库)签名,并将其发送到Amazon端点。

2)仅HMAC签名本身就是一个挑战,但现在它已经100%正确工作(根据生成的请求进行验证)。

但是,正如我前面所指出的,MWS服务器总是拒绝我的请求,同时也会出现SignatureDoesNotMatch错误,尽管它们确实是正确的。我认为唯一可能造成问题的是Indy处理POST请求的方式,特别是文本编码过程。

是否有人成功地将Delphi/Indy客户端连接到MWS?如果是,那么使用了什么样的TIdHTTP设置?我现在拥有的是:

代码语言:javascript
运行
AI代码解释
复制
procedure TAmazon.TestGetOrder(OrderID:String);

const AwsAccessKey = 'MyAccessKey';
      AwsSecretKey = 'MySecretKey';
      MerchantID = 'MyMerchantID';
      MarketplaceID = 'MyMarketplaceID';
      ApiVersion = '2013-09-01';
      CallUri = '/Orders/2013-09-01';

var HTTP:TIdHTTP;
    SSL:TIdSSLIOHandlerSocketOpenSSL;
    SS:TStringStream;
    Params:TStringList;
    S,Timestamp,QueryString,Key,Value:String;
    i:Integer;

begin
   HTTP:=TIdHTTP.Create(nil);
   SSL:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
   Params:=TStringList.Create;
   try
      Params.Delimiter:='&';
      Params.StrictDelimiter:=True;

      // HTTP Client Options
      HTTP.HTTPOptions:=HTTP.HTTPOptions+[hoKeepOrigProtocol]-[hoForceEncodeParams];
      HTTP.ConnectTimeout:=5000;
      HTTP.ReadTimeout:=20000;
      HTTP.ProtocolVersion:=pv1_1;
      HTTP.IOHandler:=SSL;
      HTTP.HandleRedirects:=True;
      HTTP.Request.Accept:='text/plain, */*';
      HTTP.Request.AcceptLanguage:='en-US';
      HTTP.Request.ContentType:='application/x-www-form-urlencoded';
      HTTP.Request.CharSet:='utf-8';
      HTTP.Request.UserAgent:='MyApp/1.0 (Language=Delphi)';
      HTTP.Request.CustomHeaders.AddValue('x-amazon-user-agent',HTTP.Request.UserAgent);

      // generate the timestamp per Amazon specs
      Timestamp:=TIso8601.UtcDateTimeToIso8601(TIso8601.ToUtc(Now));
      // we can change the timestamp to match a value from the Scratchpad as a way to validate the signature:
      //Timestamp:='2014-05-09T20:32:28Z';

      // add required parameters from API function GetOrder
      Params.Add('Action=GetOrder');
      Params.Add('SellerId='+MerchantID);
      Params.Add('AWSAccessKeyId='+AwsAccessKey);
      Params.Add('Timestamp='+Timestamp);
      Params.Add('Version='+ApiVersion);
      Params.Add('SignatureVersion=2');
      Params.Add('SignatureMethod=HmacSHA256');
      Params.Add('AmazonOrderId.Id.1='+OrderID);
      // generate the signature using the parameters above
      Params.Add('Signature='+GetSignature(Params.Text,CallUri));

      // after generating the signature, make sure all values are properly URL-Encoded
      for i:=0 to Params.Count-1 do begin
         Key:=Params.Names[i];
         Value:=ParamEnc(Params.ValueFromIndex[i]);
         QueryString:=QueryString+Key+'='+Value+'&';
      end;
      Delete(QueryString,Length(QueryString),1);

      // there are two ways to make the call...
      // #1: according to the documentation, all parameters are supposed to be in
      // the URL, and the body stream is supposed to be empty
      SS:=TStringStream.Create;
      try
         try
            Log('POST '+CallUri+'?'+QueryString);
            S:=HTTP.Post('https://mws.amazonservices.com'+CallUri+'?'+QueryString,SS);
         except
            on E1:EIdHTTPProtocolException do begin
               Log('RawHeaders='+#$D#$A+HTTP.Request.RawHeaders.Text);
               Log('Protocol Exception:'+#$D#$A+StringReplace(E1.ErrorMessage,#10,#$D#$A,[rfReplaceAll]));
            end;
            on E2:Exception do
               Log('Unknown Exception: '+E2.Message);
         end;
         Log('ResponseText='+S);
      finally
         SS.Free;
      end;

      // #2: both the Scratchpad and the CSharp client sample provided by Amazon
      // do things in a different way, though... they POST the parameters in the
      // body of the call, not in the query string
      SS:=TStringStream.Create(QueryString,TEncoding.UTF8);
      try
         try
            SS.Seek(0,0);
            Log('POST '+CallUri+' (parameters in body/stream)');
            S:=HTTP.Post('https://mws.amazonservices.com'+CallUri,SS);
         except
            on E1:EIdHTTPProtocolException do begin
               Log('RawHeaders='+#$D#$A+HTTP.Request.RawHeaders.Text);
               Log('Protocol Exception:'+#$D#$A+StringReplace(E1.ErrorMessage,#10,#$D#$A,[rfReplaceAll]));
            end;
            on E2:Exception do
               Log('Unknown Exception: '+E2.Message);
         end;
         Log('ResponseText='+S);
      finally
         SS.Free;
      end;
   finally
      Params.Free;
      SSL.Free;
      HTTP.Free;
   end;
end;

如果我在Scratchpad中组装了一个GetOrder调用,然后将该调用的时间戳粘贴到上面的代码中,我在这里得到完全相同的查询字符串,具有相同的签名和大小等。但是我的Indy请求必须以不同的方式编码,因为MWS服务器不喜欢这个调用。

我知道MWS至少在“读取”查询字符串,因为如果我将时间戳更改为旧日期,它将返回一个“请求过期”错误。

亚马逊的技术支持是毫无头绪的,每天都会发布一条基本信息,比如“确保秘密密钥是正确的”(就像用HMAC 256和MD5获得签名时没有有效的密钥一样!)

还有一件事:如果我使用Wireshark来“观察”上面代码和示例代码中的原始请求,我也看不出有什么区别。但是,我不确定Wireshark是否区分了UTF-8和ASCII,或者显示的文本所包含的任何编码。我仍然认为这与UTC-8的错误编码或类似的事情有关。

关于如何正确编码API调用以取悦亚马逊神的想法和建议是受欢迎和赞赏的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-09 20:38:16

发现了问题: Indy (和Synapse也一样)将端口号添加到"Host“标题行中,直到我更仔细地使用Fiddler来查看标题(谢谢,@Graymatter!),我才意识到这一点。

当我将端点更改为mws.amazonservices.com:443 (而不仅仅是mws.amazonservices)时,我的签名的计算方式与AWS服务器的相同,而且一切都很完美。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23573799

复制
相关文章
Amazon对接选EDI还是API
亚马逊为供应商提供EDI与API方式来进行数据的对接,供应商可通过上述两种方式与亚马逊平台进行集成,从而实现点对点自动接收订单,回传发票、ASN。
知行软件EDI
2022/05/25
7290
Amazon对接选EDI还是API
8个woocommerce支付网关插件推荐
当然您以前听说过WooCommerce吗?这是用WordPress建立在线商店的最简单方法之一。WooCommerce允许网站所有者添加产品,数字商品,甚至订​​阅(取决于您已安装的WooCommerce扩展)。但是,对于WooCommerce包含的所有强大功能,仅内置了一些默认付款选项。幸运的是,您可以添加大量免费的高级WooCommerce付款网关插件,为客户提供新的结帐选项。
Hoan外贸建站
2020/12/03
6.9K0
Serverless 时代,这才是Web应用开发正确的打开方式 | Q推荐
如同 iPhone 当年颠覆了诺基亚,Serverless 的出现也带来了一种全新的、颠覆式的云开发架构模式。在 Serverless 出现前,开发者们根本无法想象几分钟就能快速部署一个 Web 应用上线。近日,亚马逊云科技 Tech Talk 特别邀请了资深无服务器技术专家孙华带来分享《 如何高效、极简构造无服务器 Web 应用》。孙华以 Amazon Lambda 的视角介绍了无服务器 Web 应用的构造方式,并讲述了如何利用最新发布的 Lambda Function URLs 和 Lambda Adapter 进一步简化无服务器 Web 应用的开发和调试并且实现 Web 应用在 Lambda,Fargate 和 EC2 等计算平台之间平滑迁移。
深度学习与Python
2022/06/13
3.6K0
Serverless 时代,这才是Web应用开发正确的打开方式 | Q推荐
Woocommerce Trends 2020
Top Woocommerce Trends To Follow In 2020. If you have an online store and missed out on the last annual Woosesh virtual conference held a few months ago, then you’re short of information in updating yourself with the latest trends of Woocommerce.
用户4822892
2019/12/10
6030
Woocommerce Trends 2020
说说 WooCommerce 插件
玩儿过WordPress的估计都听说过WooCommerce插件吧?明月其实很早的时候就接触和体验过WooCommerce插件了,严格意义上来说WooCommerce应该是WordPress平台下开源电子商务解决方案才比较确切些,也就是说WordPress+WooCommerce就是一套电子商务解决方案了,也就是我们俗称的“在线商城”。
明月登楼的博客
2021/04/30
1.9K0
说说 WooCommerce 插件
Amazon DynamoDB 工作原理、API和数据类型介绍
DynamoDB 是 AWS 独有的完全托管的 NoSQL Database。它的思想来源于 Amazon 2007 年发表的一篇论文:Dynamo: Amazon’s Highly Available Key-value Store。在这篇论文里,Amazon 介绍了如何使用 Commodity Hardware 来打造高可用、高弹性的数据存储。想要理解 DynamoDB,首先要理解 Consistent Hashing。Consistent Hashing 的原理如下图所示:
goodspeed
2020/12/25
6K0
如何与亚马逊Amazon供应商平台集成?——EDI or API
亚马逊Amazon供应商平台支持通过EDI和API两种方式进行集成,不禁开始思考到底该选择哪种方式来集成?
知行软件EDI
2021/12/13
1.3K0
如何与亚马逊Amazon供应商平台集成?——EDI or API
woocommerce如何隐藏SKU
  有时我们不想在woocommerce网站前台显示SKU,如下图所示,因为sku一多整个排版可能会乱,那么要如何隐藏sku呢?随ytkah一起来看看
ytkah
2019/12/20
2.2K0
woocommerce如何隐藏SKU
Amazon DynamoDB
DynamoDB 是Amazon最新发布的NoSQL产品,那什么是DynamoDB呢?
阳光岛主
2019/02/19
3.1K0
禁用woocommerce默认样式stylesheet
  用woocommerce建站有时我们不想要它的默认样式,那要如何屏蔽呢?当然ytkah是不会告诉你去注释删除css代码的,默认情况下WooCommerce会嵌入3个样式表,我们可以通过在当前主题的function.php文件中添加以下代码禁用它们,
ytkah
2020/02/13
1.6K0
南桥和北桥
现代 PC 机主板主要使用 2 个超大规模芯片构成的芯片组或芯片集(Chipsets)组成:北桥(Northbridge)芯片和南桥(Southbridge)芯片。北桥芯片用于与 CPU、内存和 AGP 视频接口,这些接口具有很高的传输速率。北桥芯片还起着存储器控制作用,因此Intel 把该芯片标号为 MCH(Memory Controller Hub)芯片。南桥芯片用来管理低、中速的组件,例如,PCI 总线、IDE 硬盘接口、USB 端口等,因此南桥芯片的名称为 ICH(I/O Controller Hub)。之所以用“南、北”桥来分别统称这两个芯片,是由于在 Intel 公司公布的典型 PC 机主板上,它们分别位于主版的下端和上端(即地图上的南部和北部)位置,并起着与 CPU 进行通道桥接的作用。 --by《Linux内核完全注释》
zy010101
2020/08/20
1.7K0
woocommerce模板制作简易教程
  woocommerce是wordpress里比较好用的电商解决方案,但是制作woocommerce模板相对比较复杂,如果想用woocommerce来建一个展示型的网站,不带下单功能,我们可以很快就能把模板设计出来,下面就跟着ytkah一起来学习吧
ytkah
2019/06/24
2.8K0
woocommerce shortcode短代码调用
WooCommerce配备了很多shortcode短代码(简码),可以直接在post帖子和page页面内插入内容,方便展示产品、分类等。比如直接在文章编辑时直接插入[products],或者在php文
ytkah
2023/03/14
11.4K0
woocommerce shortcode短代码调用
woocommerce如何隐藏/显示product meta
  前面我们说了woocommerce如何隐藏SKU,那如果不想显示产品分类category和标签tag呢?我们知道SKU, Category list 和 Tag list在woocommerce产品页中统称为产品product meta,下图红框所示。1、如果想全部隐藏这些meta很简单,在当前主题function.php文件中加入下面的代码即可
ytkah
2019/12/19
3.4K0
woocommerce根据标题获取相关产品
  我们知道woocommerce的相关文章是根据分类category或标签tag来获取的,能不能实现根据标题来调取相关产品呢?get_posts() 函数可以根据库存、价格、自定义项、搜索条件等不同的标准来显示不同的相关产品,如何操作呢?随ytkah一起来看看
ytkah
2019/12/19
1.6K0
Amazon Aurora 深度探索(三)
serena
2017/08/09
3K0
Amazon Aurora 深度探索(三)
WordPress插件WooCommerce任意文件删除漏洞分析
近期,研究人员在WordPress的权限处理机制中发现了一个安全漏洞,而这个漏洞将允许WordPress插件实现提权。其中一个典型例子就是WooCommerce,该插件是目前最热门的一款电子商务插件,并且拥有400万+的安装量。简而言之,这个漏洞将允许商铺管理员删除目标服务器上的特定文件,并接管管理员帐号。
FB客服
2018/12/24
1.7K0
WooCommerce Elementor Addons – 商品页面编辑器插件
TFProduct是用于Elementor Page Builder的WooCommerce插件,帮助您在页面构建器Elementor中显示WooCommerce产品。 它是最灵活的小部件,可让您以网格,轮播,分页方式显示WooCommerce产品,并加载更多布局。它可以显示编号显示产品,最新产品,特色产品,畅销产品,销售产品,最高评分产品,混合订单产品,类别产品。此外,我们还提供了完全免费的Elementor Themesflat附加组件,以及YouTube窗口小部件。您可以完全创建带有完整的页眉页脚滑块,图像框,轮播框和所有Elementor Free小部件的专业视频网站。
小狐狸说事
2022/12/30
2.2K0
WooCommerce Elementor Addons – 商品页面编辑器插件
Amazon Dynamo系统架构
本文参考了网上众多文章,把 Amazon Dynamo 架构汇总成文,为后续源码分析奠定基础。
罗西的思考
2021/02/04
1.5K0
点击加载更多

相似问题

鼠标拖动的OpenGL翻译点

13

C++ OpenGL用鼠标拖动多个对象

14

如何用OpenGL绘制鼠标拖动上的连续点

12

用OpenGL在拖动鼠标上绘制不连续线

11

用C++和OpenGL拖动三维对象

15
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文