这是我的第一个oAuth1项目。我正在尝试连接到FitBit的API。我去了fitbit,注册了一个应用程序并记录了我的密钥和秘密。
我已经下载并尝试设置: http://oauth.riaforge.org/
1)我发现在尝试通过SSL连接时出现连接失败..但我认为这是一个密钥库问题。当我回到http时,它至少尝试连接:
2)我目前正在使用examples_external / google.cfm文件中的代码。这似乎是最接近的比赛。
当我运行代码时,我收到下面提到的响应。我假设oauth客户端发送链接作为获取URL中的所有值,Fitbit想要一个POST,它需要一个身份验证标头。我已经研究过了,但Fitbit和Oauth的CF例子很缺乏。
这是他们正在寻找的东西。 https://wiki.fitbit.com/display/API/OAuth+Authentication+in+the+Fitbit+API
任何指导都将不胜感激。
<!--- set up the parameters --->
<cfset sConsumerKey = "xxxxx"> <!--- FromFit Bit --->
<cfset sConsumerSecret = "yyyy"> <!--- From FitBit --->
<cfset sTokenEndpoint = "http://api.fitbit.com/oauth/request_token"> <!--- Access Token URL --->
<cfset sAuthorizationEndpoint = "http://www.fitbit.com/oauth/authorize"> <!--- Authorize URL --->
<cfset sCallbackURL = "http://www.example.com/fitbit/callback.cfm"> <!--- where fitbit will redirect to after the user enters their details --->
<cfset sClientToken = ""> <!--- returned after an access token call --->
<cfset sClientTokenSecret = ""> <!--- returned after an access token call --->
<cfset sScope =''> <!--- required for google --->
<!--- set up the required objects including signature method--->
<cfset oReqSigMethodSHA = CreateObject("component", "oauth.oauthsignaturemethod_hmac_sha1")>
<cfset oToken = CreateObject("component", "oauth.oauthtoken").createEmptyToken()>
<cfset oConsumer = CreateObject("component", "oauth.oauthconsumer").init(sKey = sConsumerKey, sSecret = sConsumerSecret)>
<cfset Parameters = structNew()>
<cfset parameters.scope = sScope>
<cfset oReq = CreateObject("component", "oauth.oauthrequest").fromConsumerAndToken(
oConsumer = oConsumer,
oToken = oToken,
sHttpMethod = "GET",
sHttpURL = sTokenEndpoint,stparameters=Parameters )>
<cfset oReq.signRequest(
oSignatureMethod = oReqSigMethodSHA,
oConsumer = oConsumer,
oToken = oToken)>
<cfhttp url="#oREQ.getString()#" method="get" result="tokenResponse"/>
<!--- grab the token and secret from the response if its there--->
<cfif findNoCase("oauth_token",tokenresponse.filecontent)>
<cfset sClientToken = listlast(listfirst(tokenResponse.filecontent,"&"),"=")>
<cfset sClientTokenSecret = listlast(listlast(tokenResponse.filecontent,"&"),"=")>
<!--- you can add some additional parameters to the callback --->
<cfset sCallbackURL = sCallbackURL & "?" &
"key=" & sConsumerKey &
"&" & "secret=" & sConsumerSecret &
"&" & "token=" & sClientToken &
"&" & "token_secret=" & sClientTokenSecret &
"&" & "endpoint=" & URLEncodedFormat(sAuthorizationEndpoint)>
<cfset sAuthURL = sAuthorizationEndpoint & "?oauth_token=" & sClientToken & "&" & "oauth_callback=" & URLEncodedFormat(sCallbackURL) >
<cflocation url="#sAuthURL#">
<cfelse>
<cfoutput>#tokenResponse.filecontent#</cfoutput>
</cfif>
返回
{"errors":[{"errorType":"oauth","fieldName":"n/a","message":"No Authorization header provided in the request. Each call to Fitbit API should be OAuth signed"}],"success":false}
更新:我能够进一步了解一个例子,我找到了一个与类似问题连接到facebook的人....更新代码:
<!--- set up the parameters --->
<cfset sConsumerKey = "xxxxx"> <!--- FromFit Bit --->
<cfset sConsumerSecret = "xxxxxxxx"> <!--- From FitBit --->
<cfset sTokenEndpoint = "http://api.fitbit.com/oauth/request_token"> <!--- Access Token URL --->
<cfset sAuthorizationEndpoint = "http://api.fitbit.com/oauth/authorize"> <!--- Authorize URL --->
<cfset sCallbackURL = "http://www.example.com/fitbit/callback.cfm"> <!--- where fitbit will redirect to after the user enters their details --->
<cfset sClientToken = ""> <!--- returned after an access token call --->
<cfset sClientTokenSecret = ""> <!--- returned after an access token call --->
<!--- set up the required objects including signature method--->
<cfset oReqSigMethodSHA = CreateObject("component", "oauth.oauthsignaturemethod_hmac_sha1")>
<cfset oToken = CreateObject("component", "oauth.oauthtoken").createEmptyToken()>
<cfset oConsumer = CreateObject("component", "oauth.oauthconsumer").init(sKey = sConsumerKey, sSecret = sConsumerSecret)>
<cfset Parameters = structNew()>
<cfset oReq = CreateObject("component", "oauth.oauthrequest").fromConsumerAndToken(
oConsumer = oConsumer,
oToken = oToken,
sHttpMethod = "POST",
sHttpURL = sTokenEndpoint,stparameters=Parameters )>
<cfset oReq.signRequest(
oSignatureMethod = oReqSigMethodSHA,
oConsumer = oConsumer,
oToken = oToken)>
<cfhttp url="#oReq.GETNORMALIZEDHTTPURL()#" method="post" result="tokenresponse">
<cfhttpparam type="header" name="Authorization" value="#oReq.TOHEADER()#" />
</cfhttp>
<!---
FROM HERE DOWN IS ALL FROM EXAMPLE FILE
grab the token and secret from the response if its there--->
<cfif findNoCase("oauth_token",tokenresponse.filecontent)>
<cfset sClientToken = listlast(listfirst(tokenResponse.filecontent,"&"),"=")>
<cfset sClientTokenSecret = listlast(listlast(tokenResponse.filecontent,"&"),"=")>
<!--- you can add some additional parameters to the callback --->
<cfset sCallbackURL = sCallbackURL & "?" &
"key=" & sConsumerKey &
"&" & "secret=" & sConsumerSecret &
"&" & "token=" & sClientToken &
"&" & "token_secret=" & sClientTokenSecret &
"&" & "endpoint=" & URLEncodedFormat(sAuthorizationEndpoint)>
<cfset sAuthURL = sAuthorizationEndpoint & "?oauth_token=" & sClientToken & "&" & "oauth_callback=" & URLEncodedFormat(sCallbackURL) >
<cflocation url="#sAuthURL#">
<cfelse>
<cfoutput>#tokenResponse.filecontent#</cfoutput>
</cfif>
然而,现在我正在回调....我认为它看起来很相似,但只是附加了2个值,但我似乎无法正确追加它。
<cfset sConsumerKey = ""> <!--- FromFit Bit --->
<cfset sConsumerSecret = ""> <!--- From FitBit --->
<cfset sTokenEndpoint = "http://api.fitbit.com/oauth/request_token"> <!--- Access Token URL --->
<cfset sAuthorizationEndpoint = "http://api.fitbit.com/oauth/authorize"> <!--- Authorize URL --->
<cfset sCallbackURL = "http://www.example.com/fitbit/callback.cfm"> <!--- where fitbit will redirect to after the user enters their details --->
<cfset sClientToken = "#url.oauth_token#"> <!--- returned after an access token call --->
<cfset sClientTokenSecret = "#url.oauth_verifier#"> <!--- returned after an access token call --->
<!--- set up the required objects including signature method--->
<cfset oReqSigMethodSHA = CreateObject("component", "oauth.oauthsignaturemethod_hmac_sha1")>
<cfset oToken = CreateObject("component", "oauth.oauthtoken").createEmptyToken()>
<cfset oConsumer = CreateObject("component", "oauth.oauthconsumer").init(sKey = sConsumerKey, sSecret = sConsumerSecret)>
<cfset Parameters = structNew()>
<cfset parameters.oauth_token=url.oauth_token>
<cfset parameters.oauth_verifier=url.oauth_verifier>
<cfset oReq = CreateObject("component", "oauth.oauthrequest").fromConsumerAndToken(
oConsumer = oConsumer,
oToken = oToken,
sHttpMethod = "POST",
sHttpURL = sTokenEndpoint,stparameters=Parameters )>
<cfset oReq.signRequest(
oSignatureMethod = oReqSigMethodSHA,
oConsumer = oConsumer,
oToken = oToken)>
Header:<Cfdump var="#oreq.toheader()#"><br>
<cfhttp url="http://api.fitbit.com/oauth/access_token" method="post" result="tokenresponse">
<cfhttpparam type="header" name="Authorization" value="#oReq.TOHEADER()#" />
</cfhttp>
我将返回以下错误:
{"errors":[{"errorType":"oauth","fieldName":"oauth_access_token","message":"Invalid signature or token 'xxxxxxxxxxxxxxxxxxxxxxx' or token 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'"}],"success":false}
这似乎是因为验证者和令牌没有出现在标题内(或任何地方)......
所以基本上我认为一个好的oauth回调文件示例会让我走上正轨。
答案 0 :(得分:1)
让我先说明我没有使用FitBit API。从您收到的错误和您提供的链接,API要求授权标头包含在请求中。以下是如何在ColdFusion cfhttp
调用中包含HTTP标头的示例。
您引用的API文档提到请求需要以下授权标头参数:
- oauth_callback - 回调网址。服务器存储此URL,并在用户授权客户端时重定向到该URL。
- oauth_consumer_key - 注册时同意的客户密钥。
- oauth_nonce - 客户端唯一生成的随机字符串,用于允许服务器验证请求的唯一性。
- oauth_signature - 根据OAuth 1.0协议第3.4节:签名计算的签名。
- oauth_signature_method - 签名方法:HMAC-SHA1
- oauth_timestamp - 时间戳
- oauth_version - 1.0
从他们的示例中,您的ColdFusion代码看起来像这样:
<cfhttp url="#oREQ.getString()#" method="get" result="tokenResponse">
<cfhttpparam type="header" name="oauth_callback" value="http%3A%2F%2Fexample.fitbit.com%2Fapp%2FcompleteAuthorization" />
<cfhttpparam type="header" name="oauth_consumer_key" value="fitbit-example-client-application" />
<cfhttpparam type="header" name="oauth_nonce" value="161822064" />
<cfhttpparam type="header" name="oauth_signature" value="Omf%2Bls2gn%2BDlghq245LRIyfMdd8%3D" />
<cfhttpparam type="header" name="oauth_signature_method" value="HMAC-SHA1" />
<cfhttpparam type="header" name="oauth_timestamp" value="1270248082" />
<cfhttpparam type="header" name="oauth_version" value="1.0" />
</cfhttp>
希望这足以让你更进一步。
更新
我确实遇到了一些传递参数的other oauth examples。如果前一个方法不起作用,以下是该方法的示例:
<cfhttp url="#oREQ.getString()#" method="get" result="tokenResponse">
<cfhttpparam type="header" name="content-type" value="application/x-www-form-urlencoded">
<cfhttpparam type="oauth_callback" name="FormField" value="http%3A%2F%2Fexample.fitbit.com%2Fapp%2FcompleteAuthorization" />
<cfhttpparam type="oauth_consumer_key" name="FormField" value="fitbit-example-client-application" />
<cfhttpparam type="oauth_nonce" name="FormField" value="161822064" />
<cfhttpparam type="oauth_signature" name="FormField" value="Omf%2Bls2gn%2BDlghq245LRIyfMdd8%3D" />
<cfhttpparam type="oauth_signature_method" name="FormField" value="HMAC-SHA1" />
<cfhttpparam type="oauth_timestamp" name="FormField" value="1270248082" />
<cfhttpparam type="oauth_version" name="FormField" value="1.0" />
</cfhttp>