我遇到了一个无效签名的错误。我正在调用itemsearch API,但在此之前我的签名(版本4)无效。
这是cfc文件" amazonsig.cfc"我是从http://amazonsig.riaforge.org/index.cfm?event=action.download得到的:
<cfcomponent hint="Amazon Product Advertising API Signature Generator">
<cffunction name="signRequest" returntype="string" output="false"
hint="Sign a request">
<cfargument name="request" required="yes" type="string">
<cfargument name="secretKey" required="yes" type="string">
<!--- "Local" variable scope --->
<cfset var lc = structnew()>
<!--- Extract the URL part of the request and strip the protocol --->
<cfset lc.requesturl = listfirst(arguments.request, "?")>
<cfset lc.requesturl = replacenocase(lc.requesturl, "http://", "")>
<!--- Split into host and path --->
<cfset lc.host = listfirst(lc.requesturl, "/")>
<cfset lc.path = right(lc.requesturl, len(lc.requesturl) - len(lc.host))>
<!--- Process the query string parameters into a structure --->
<cfset lc.querystring = listlast(arguments.request, "?")>
<cfset lc.strParams = structnew()>
<cfloop list="#lc.querystring#" index="i" delimiters="&">
<cfset lc.strParams[listfirst(i, "=")] = urldecode(listlast(i, "="))>
</cfloop>
<!--- Add the timestamp --->
<cfif not StructKeyExists(lc.strParams, "Timestamp")>
<cfset lc.utcdate = dateconvert("local2Utc", now())>
<cfset lc.timestamp = dateformat(lc.utcdate, 'yyyy-mm-dd') & "T" & timeformat(lc.utcdate, 'HH:mm:ss') & "Z">
<cfset lc.strParams["Timestamp"] = lc.timestamp>
</cfif>
<!--- Sort the parameters --->
<cfset lc.keys = listsort(structkeylist(lc.strParams), "text")>
<!--- Generate a new query string including timestamp, with parameters in the correct order, encoding as we go --->
<cfset lc.qs = "">
<cfloop list="#lc.keys#" index="i">
<cfset lc.qs = lc.qs & rfc3986EncodedFormat(i) & "=" & rfc3986EncodedFormat(lc.strParams[i]) & "&">
</cfloop>
<!--- Strip off the last & --->
<cfset lc.qs = left(lc.qs, len(lc.qs)-1)>
<!--- Build the string to sign --->
<cfset lc.stringToSign = "GET" & chr(10)>
<cfset lc.stringToSign = lc.stringToSign & lc.host & chr(10)>
<cfset lc.stringToSign = lc.stringToSign & lc.path & chr(10)>
<cfset lc.stringToSign = lc.stringToSign & lc.qs>
<!--- Create the signature --->
<cfset lc.binaryMsg = JavaCast("string",lc.stringToSign).getBytes("iso-8859-1")>
<cfset lc.binaryKey = JavaCast("string",arguments.secretKey).getBytes("iso-8859-1")>
<cfset lc.key = createObject("java","javax.crypto.spec.SecretKeySpec")>
<cfset lc.key.init(lc.binaryKey,"HmacSHA256")>
<cfset lc.hmac = createObject("java","javax.crypto.Mac")>
<cfset lc.hmac = lc.hmac.getInstance("HmacSHA256")>
<cfset lc.hmac.init(lc.key)>
<cfset lc.hmac.update(lc.binaryMsg)>
<cfset lc.signature = lc.hmac.doFinal()>
<!--- Return the new request URL --->
<cfreturn "http://" & lc.host & lc.path & "?" & lc.qs & "&Signature=" & urlencodedformat(tobase64(lc.signature))>
</cffunction>
<cffunction name="rfc3986EncodedFormat" returntype="string" output="false"
hint="Perform some character encoding">
<cfargument name="text" required="yes" type="string">
<!--- "Local" variable scope --->
<cfset var lc = structnew()>
<cfset lc.objNet = createObject("java","java.net.URLEncoder")>
<cfset lc.encodedText = lc.objNet.encode(arguments.text, 'utf-8').replace("+", "%20").replace("*", "%2A").replace("%7E", "~")>
<cfreturn lc.encodedText>
</cffunction>
</cfcomponent>
这是我的cfm文件&#34; amazonsig.cfm&#34;
<cfset requrl = "http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&Operation=ItemSearch&AWSAccessKeyId=aaaa&AssociateTag=aaaaa&SearchIndex=Books&Keywords=Harry&ResponseGroup=Images,ItemAttributes,Offers">
<cfset amazonsig = createObject("component", "amazonsig")>
<cfset abc = amazonsig.signrequest(requrl,"aaa")>
<cfhttp url="#abc#" method="GET" result="response" resolveurl="yes">
<cfhttpparam type="header" name="Content-Type" value="application/json" >
<cfhttpparam type="header" name="Accept" value="application/json" >
</cfhttp>
<cfdump var="#response#">
注意:签名网址是正确的,因为我直接在浏览器中点击并且响应正确返回,但在&lt; cfhttp&gt;中这是错误的。
答案 0 :(得分:0)
我已经解决了,我使用的是coldfusion 11和jdk 1.7,但是当我使用jdk 1.8在coldfusion 10上运行代码时,它已成功运行。