Tuesday, 14 May 2013

Fixing Twitter OAuth 401 errors due to server time

So if you're like me, your Twitter app (youpickedafinetimetoleaveme.com) had been happily authorizing user access tokens and secrets via OAuth against Twitter since forever, then all of a sudden bang! You start getting stack traces all over your browser with an Exception a bit like this:

"oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match."
(For the record, I'm using the excellent Signpost OAuth Java library to handle the low level OAuth functionality, but this error would happen regardless how you handle your OAuth authorizations...)

Now I have a guilty little secret to share. A while back, Twitter updated their API, and there was all this fuss about legacy apps breaking, and well, you know what - mine didn't break, so I ignored all of that, did nothing and went about my day. Until now. Seeing this error happen I thought my laziness had come home to roost. Not an uncommon feeling. So I went and updated the aforementioned Signpost, along with JTwitter and Scribe (it's a long story), and updated some code, and tests pass and it works on my machine just fine, but you know what - when I uploaded it to production it didn't fix a thing.

The actual problem is kinda implied in that last part of the Exception message - "...the signatures did not match". It turns out my Debian server clock time was incorrect. Twitter will 401 an OAuth attempt if the signature is not correct - and sender machine DateTime is part of that check. Local clock was fine.

To check if this is your problem, from the server command line type

date

and if that date doesn't look right, this is probably your problem. Even if it isn't, having your server in sync can only be a good thing, right? Press on to see how to update your server clock on Debian.

Turns out more recent distributions of Debian have some issue that prevents clock sync from the server hardware - so they generally drift out of time unless you are running something that keeps it in sync via NTP. So the solution to this problem is simples:  update your server clock.

Here's how I did that, from command line on the server machine:

1. Install ntp to keep the machine in sync, and ntpdate as a manual sync utility 

sudo aptitude update 
sudo aptitude install ntp 
sudo aptitude install ntpdate


2. Check the current server date

date

3. Sync via a remote time server

sudo ntpdate pool.ntp.org


4. Check the current server data again, it should be different now, dare we say it - correct?

date


5. Lastly, set ntp started on your machine

/etc/init.d/ntp start


And you're done.