我正在尝试与亚马逊产品会员REST API集成,我拒绝使用SOAP集成,并且请不要在此提出肥皂,我想使用REST,我正在使用最新API版本,这是2013年8月1日我跟随的文档,不知何故,我总是回来一个403禁止的错误,我看遍了各地,我看到的唯一的事情是,对过时的样品在亚马逊,所以我感到沮丧,没有得到我的集成工作,这是我使用的规格。亚马逊产品会员REST API集成
VS 2015年 控制台应用程序针对.NET 4.5.2 亚马逊API版本2013年8月1日
,这里是我的代码库。
我有一个称为AmazonRestService 类,其具有所需的ItemLookup所有属性,
在构造我设置一些特性,这是默认为每一个请求,那么我有一个称为SignAmazonRequest 方法,该方法需要一个AmazonRestService作为参数,和我确认有一个值的所有领域,我填满,将需要签名的字符串,
public class AmazonRestService
{
public string Url { get; set; }
public string Operation { get; set; }
public string AWSAccessKeyId { get; set; }
public string SecretKey { get; set; }
public string AssociateTag { get; set; }
public string ItemId { get; set; }
public string IdType { get; set; }
public string[] ResponseGroup { get; set; }
public string Timestamp { get; set; }
public string Signature { get; set; }
public string Version { get; set; }
public AmazonRestService()
{
Url = "http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&";
AWSAccessKeyId = "XXXXXXXXXXXXXXXXXXXXX";
AssociateTag = "xxxx-xx";
SecretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
Version = "2013-08-01";
}
public AmazonRestService SignAmazonRequest(AmazonRestService service)
{
var stringToSign = "";
stringToSign = stringToSign + "AssociateTag=" + service.AssociateTag;
if (!string.IsNullOrEmpty(service.Operation))
{
stringToSign = stringToSign + "&Operation=" + service.Operation;
}
if (!string.IsNullOrEmpty(service.ItemId))
{
stringToSign = stringToSign + "&ItemId=" + service.ItemId;
}
if (!string.IsNullOrEmpty(service.IdType))
{
stringToSign = stringToSign + "&IdType=" + service.IdType;
}
if (service.ResponseGroup.Length > 0)
{
stringToSign = stringToSign + "&ResponseGroup=";
var lastResponse = service.ResponseGroup.Last();
foreach (var response in service.ResponseGroup)
{
stringToSign = stringToSign + response;
if (response != lastResponse)
{
stringToSign = stringToSign + ",";
}
}
}
stringToSign = stringToSign + "&Version=" + service.Version;
stringToSign = stringToSign + "&AWSAccessKeyId=" + service.AWSAccessKeyId + "&Timestamp=" + service.Timestamp;
stringToSign = stringToSign.Replace(",", "%2C");
stringToSign = stringToSign.Replace(":", "%3A");
service.Url = service.Url + stringToSign;
stringToSign = stringToSign + "&Service=AWSECommerceService";
service.Signature = HmacSha256.SignAmazonRequest(service.SecretKey, stringToSign);
service.Url = service.Url + "&Signature=" + service.Signature;
return service;
}
}
一旦字符串是准备要签名,我请了一个名为HmacSha256.SignAmazonRequest 在那里我通过我的秘密密钥和字符串将签署不同类的静态mehod,
public static class HmacSha256
{
public static string SignAmazonRequest(string secretKey, string request)
{
var stringToSign = PrepareSignatureEncryption(request);
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
var hmacSha256 = new HMACSHA256(secretKeyBytes);
var hashBytes = hmacSha256.ComputeHash(bytesToSign);
return Convert.ToBase64String(hashBytes).Replace("+", "%2B").Replace("=", "%3D");
}
private static string PrepareSignatureEncryption(string request)
{
var header = "GET" + Environment.NewLine
+ "webservices.amazon.com" + Environment.NewLine
+ "/once/xml" + Environment.NewLine;
var result = header + request;
return result;
}
}
里面的SignAmazonRequest方法,我第一次准备字符串为亚马逊想要它,
我有一个私人帮手方法称为PrepareSignatureEncryption 它需要str将其作为参数进行签名,并返回已准备格式化的字符串,如亚马逊在其文档中所示, 然后将字符串转换为字节, 我将密钥转换为字节, 基于密钥字节生成HMACSHA256, 与我计算的字符串散列签名, 我返回的字节转换为base64字符串,
现在与所有,这是我的代码在静态无效的主要。
class Program
{
static void Main(string[] args)
{
var restService = new AmazonRestService();
restService.Operation = "ItemLookup";
restService.IdType = "ASIN";
restService.ItemId = "ASINTOLOOKUP";
restService.ResponseGroup = new string[] { "BrowseNodes", "Images", "ItemAttributes", "Offers", "Reviews", "SalesRank" };
var signedRequest = restService.SignAmazonRequest(restService);
Console.WriteLine(signedRequest.Url);
Console.ReadLine();
try
{
var request = WebRequest.Create(signedRequest.Url);
var response = request.GetResponse();
var doc = new XmlDocument();
doc.Load(response.GetResponseStream());
doc.Save("C:/data.xml");
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
}
我下面这个文档,https://aws.amazon.com/archives/Product-Advertising-API/8967000559514506
任何想法,我走到哪里错了?
我试着http://webservices.amazon.com/scratchpad/index.html,一切工作在那里,我试图在我的代码中使用相同的时间戳,并且一切看起来与在暂存器上完全相同,按字节排序,但签名是不同的,任何人都会对此有所评论? –