Drupal Services And The Dreaded Clock

Photo of Greg Harvey
Fri, 2009-12-11 18:21By greg

Quick post this evening, because I'm stopping for the day. Just a troubleshooting tip for web services. We use the excellent Drupal Services module quite a lot for integration work. Take a look, if you don't know it:
http://drupal.org/project/services

Anyway, we always switch on the full security options, which are great for securing the API but stacked full of nasty gotchas. I had a new one today and I thought I'd share.

Part of building an authentication token for the Drupal Services module is adding in a timestamp. The code we normally use looks like this:

// set vars for this connection
$nonce = getUniqueCode("10");
$method_name = 'user.login';
$timestamp = (string) strtotime("now");
$required_args = array();

// now prepare a hash
$hash_parameters = array(
$timestamp,
$domain,
$nonce,
$method_name,
);

$hash = hash_hmac("sha256", implode(';', $hash_parameters), $kid);

// prepared the arguments for this service
$required_args = array(
$hash,
$domain,
$timestamp,
$nonce,
$response['sessid'],
);
?>

This wasn't working on our live server, but it was working on test and on two separate local machines. It was killing us! We were trying to think of everything, PHP version, Linux distro, user permissions, what can it be?

Having just about run out of ideas, I posted in the Services issue queue and was rescued once again. Check it out:
http://drupal.org/node/657368

Time! The error message (which was partially masked by a bug with Services) was actually "Token has expired". It was heyrocker saying the immortal words "those servers aren't in different timezones, are they?" that put me on to the fix.

Actually, timezones don't matter. That's because a timestamp is a timestamp and they're all UTC. Timezone is just a local conversion the machine does so we feeble humans don't get confused. What *was* the problem was the server's clock was wrong!

So, if you're having Services authentication issues add this one to your checklist:

Make sure the server clock (and, indeed, your computer's clock) are correct. Or at least wrong to the same degree.

Just one more thing, in the words of Columbo...

To see the *real* authentication errors from your XML-RPC services, while a bug fix is pending for the errors not getting passed back correctly, add this line at the start of the xmlrpc_server.module's xmlrpc_server_server_error() function:

watchdog('debug', '

'. htmlspecialchars(print_r($message, true)) .'

');
?>

This will put your XML-RPC errors in to the Drupal log, so at least you have them somewhere. See this issue for details:
http://drupal.org/node/657444