Home Archives Search Feed


Websocket API & Authentication

Some months ago I was looking for a way to authenticate a websocket endpoint on Poxas console. The answer in the end was easy. The same way that Pusher signs HTTP requests: a simple HMAC-SHA256 applied on the payload with a secret. The interesting part is that the payload is well defined. Here’s an example from the Pusher website:

It’s always composed as:

POST\n/apps/3/events\nauth_key=278d425bdf160c739803&auth_timestamp=1353088179&auth_version=1.0&body_md5=ec365a775a4cd0599faeb73354201b6f

This string is joined by \n and then signed using HMAC-SHA256 with the secret related to this key.

The last key value added to the query string is auth_signature which is the result of signing.

Which properties do you get with this?

In the end, any change on the request will mess up with the expected signature and invalidate it.

If you notice that a Websocket connection is started as a GET request, you can easily use this signing method to achieve the same properties.

On the client side, in this case the browser, I just used crypto-js with jQuery param:

function authQS(appKey, secret) {
  var auth_key = appKey;
  var auth_timestamp = Math.round(new Date().getTime() / 1000);
  var params = { auth_key:auth_key,
                 auth_timestamp:auth_timestamp,
                 auth_version:"1.0" } ;
  var auth_signature = CryptoJS.HmacSHA256("GET\n/console\n" + $.param(params), secret).toString();
  return $.param($.extend({ }, params, { auth_signature:auth_signature }));
}

var qs = authQS(appKey, secret);
var host = window.location.host;
websocket = new WebSocket("ws://" + host  + "/console?" + qs);

On the backend side I used signaturex(written in Elixir), but you could use the original ruby library signature.

That’s it! Don’t forget to use SSL on top of it so you can encrypt everything.

Posted on October 11, 2014   #websocket     #pusher  






← Next post