views:

226

answers:

2

Hi all, I've been battling with OAuth and Twitter for 2 weeks now trying to implement it. After many rewrites of my code I've finally got a library which performs the request as it should be based on the 1.0 spec. I've verified it by using this verifier on Google Code, and this verifier from Hueniverse.

My version, the Google version and the Hueniverse version all produce the exact same signature, so I've concluded that I am no longer the cause (but I could be putting a foot in my mouth by stating this...).

I test my implementation by first creating a test request using Twitter's API Console, in this case a status update. I copy the params that change, the oauth_nonce and oauth_timestamp, into all three signers stated above. All other params are always the same, tokens/secrets/etc.

Twitter's console produces one signature, but the other three above all produce a different signature (from Twitter's, identical to each other).

So, my question is, why am I getting this:

<?xml version="1.0" encoding="UTF-8"?>
<hash>
    <request>/1/statuses/update.xml</request>
    <error>Could not authenticate with OAuth.</error>
</hash>

...when I should be implementing the spec to the "T"?

Is there something specific that Twitter needs/wants as part of the request? I've counted the nonce generated by Twitter as 42 chars long, is that correct? Should it be 42 chars long?

I would appreciate help from anyone with more insight into the API than I obviously have...

Thanks in advance!

UPDATE: Someone asked about how I send the authentication params, but has since deleted their post, idk why. Anyway, the authorization params are sent via the Authorization header.

UPDATE/SOLUTION: Is moved down to the bottom where it belongs as an answer.

+2  A: 

The only problem I had when implementing the OAuth specification with Twitter as the main target was, that Twitter has restricted the nonce to only accept ASCII characters (while the specification actually allows any bytes). Therefor I changed my implementation to generate a random int (with 60 bits, so longer than 42 chars) instead.

Other than that, Twitter's implementation seems to be completely correct; at least I didn't have any issues.

I suggest you to use some of the many OAuth sandboxes around (for example this or this) to really check if everything goes right and for example if you include everything necessary into the signature etc..

poke
Well, I figured it out, and it was quite dumb... Answer above. Anyway, on the topic of the nonce, I have a function that loops through a-z, A-Z, 0-9 and builds me a string which will always be ASCII, so I'm good there, I think.
Alex
Good to hear :) But you might want to move your own answer into a new response to this question and accept that, to mark the question as resolved. Otherwise, it will stay open.
poke
A: 

A little late, but per @poke's suggestion, I'm adding my answer down here:

So, I figured it out, and it's actually quite stupid. A while back, probably rewrite 3, I was getting back bad non-XML response from Twitter. I then saw that in the Twitter API Console they escape the header params: param=\"value\". I added the backslash to mine and instantly I was getting back an XML response. So it stuck.

Anyway, just to rule everything out from rewrite 7 (or 8), I decided to remove the backslash from the header params string and it resolved everything.

So, the lesson learned from all of this is that not everything that the Twitter API Console displays should be mimicked. I actually would further suggest that Twitter updates the console to display what a header string should look like when sent and not what their system generates internally, which parses the backslash chars.

Alex