2
votes

we're trying to use ColdFusion 9 to post an update to Twitter via its API v. 1.1, but despite everything looking like it should work, we continue to get 401 "Unauthorized" errors. Any help would be most appreciated!

Looking back through previous posts here reinforces the belief that we're doing everything correctly, but perhaps there is something assumed that we're missing.

None of the following three approaches work for us (update is in a formfield; update is in a body field; update is part of the URL.):

<cfhttp url="https://api.twitter.com/1.1/statuses/update.json" method="POST" throwonerror="yes">
    <cfhttpparam type="header" name="Authorization" value="OAuth oauth_consumer_key="vAA11oLz0R7kigH0iXwjQ", oauth_nonce="3D18D32A07048D54724AA0F304E83CFF", oauth_signature="TaEA6Ip9AJ07QKTxcWWT4fzPNpA%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1386088450", oauth_token="82684171-ptqIw8uOz0KNwBEL4AO7ue8DpzciWSNKvUqDoAf8p", oauth_version="1.0" ">
    <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded">
    <cfhttpparam type="formfield" name="status" value="HelloWorld" encoded="yes">
</cfhttp>



<cfhttp url="https://api.twitter.com/1.1/statuses/update.json" method="POST" throwonerror="yes">
    <cfhttpparam type="header" name="Authorization" value="OAuth oauth_consumer_key="vAA11oLz0R7kigH0iXwjQ", oauth_nonce="3D18D32A07048D54724AA0F304E83CFF", oauth_signature="TaEA6Ip9AJ07QKTxcWWT4fzPNpA%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1386088450", oauth_token="82684171-ptqIw8uOz0KNwBEL4AO7ue8DpzciWSNKvUqDoAf8p", oauth_version="1.0" ">
    <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded">
    <cfhttpparam type="body" value="status=HelloWorld" encoded="yes">
</cfhttp>



<cfhttp url="https://api.twitter.com/1.1/statuses/update.json?status=HelloWorld" method="POST" throwonerror="yes">
    <cfhttpparam type="header" name="Authorization" value="OAuth oauth_consumer_key="vAA11oLz0R7kigH0iXwjQ", oauth_nonce="3D18D32A07048D54724AA0F304E83CFF", oauth_signature="TaEA6Ip9AJ07QKTxcWWT4fzPNpA%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1386088450", oauth_token="82684171-ptqIw8uOz0KNwBEL4AO7ue8DpzciWSNKvUqDoAf8p", oauth_version="1.0" ">
    <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded">
</cfhttp>

The Twitter account has read/write access granted for this app. We are encoding according to directions at https://dev.twitter.com/docs/auth/authorizing-request and https://dev.twitter.com/docs/auth/creating-signature and we have seen these SO pages: ColdFusion Twitter API Bad Request, ColdFusion Post To Twitter Authentication Error, Twitter, oauth and coldfusion, Twitter API status update not working when updating to v1.1 and we tried Apigee.

We're using our access token and its secret to generate the signature. What are we missing here? Is this supposed to be a single-step process to post an update, or do we need to have a step that authenticates or authorizes before we try to post? The OAuth tool tab on the Twitter dev site generates the same headers, etc., that our ColdFusion script produces.

-Ken

1
monkehtweet is the way to go Ken. download it and use it... it will save you pulling out your hair. Meanwhile you should NOT post actual keys and signatures in your sample code unless you want to invite nefarious hackers :)Mark A Kruger
Hi Mark - keys and tokens were reset, so no worries there. We did try monkehtweet but found that even more hair-pulling and this route appeared to be far simpler for the single purpose of posting tweets.Ken Stuart

1 Answers

2
votes

When dealing with OAuth in CF I always use this library: http://oauth.riaforge.org/

This is a bit of script I use to send status updates then (it's taken out of the context, but should give you some ideas):

<cfscript>
    //cfcs - from the OAuth library
    oauthSigMethodSHA = CreateObject("component", "OAuth.oauthsignaturemethod_hmac_sha1");
    oauthRequestCFC = CreateObject("component", "OAuth.oauthrequest");
    oauthConsumerCFC = CreateObject("component", "OAuth.oauthconsumer");
    oauthTokenCFC = CreateObject("component", "OAuth.oauthtoken");

    oTwitterConsumer = oauthConsumerCFC.init(sKey = MyConsumerKey, sSecret = MyConsumerSecret);

    ParamsStruct = StructNew();
    ParamsStruct['status'] = MyStatus;

    oTwitterAccessToken = oauthTokenCFC.init(sKey = MyAccessToken, sSecret = MyAccessSecret);

    //create request
    oTwitterReqest = oauthRequestCFC.fromConsumerAndToken(
        oConsumer   : oTwitterConsumer,
        oToken      : oTwitterAccessToken,
        sHttpMethod : "POST",
        sHttpURL    : 'https://api.twitter.com/1.1/statuses/update.json',
        stParameters: ParamsStruct
    );

    //sign request
    oTwitterReqest.signRequest(
        oSignatureMethod    : oauthSigMethodSHA,
        oConsumer           : oTwitterConsumer,
        oToken              : oTwitterAccessToken
    );
</cfscript>

<cfhttp method="POST" url="#oTwitterReqest.getString()#" result="result" throwonerror="no" charset="utf-8" redirect="no">
    <cfhttpparam type="header" name="status" value="#MyStatus#">
</cfhttp>