Authenticate socket.io incoming connections with JWTs. https://www.npmjs.com/package/@thream/socketio-jwt
This repository has been archived on 2024-11-11. You can view files and clone it, but cannot push or open issues or pull requests.
Go to file
gfetco 170c23306f Validation
on socket authenticate, should check that the data.token exists and if it is the desired type? 
socket.emit( 'authenticate', {token: {} }); // will crash server if sent from client-side.
2015-11-01 20:44:25 +01:00
example minor 2015-08-31 11:09:22 -03:00
lib Validation 2015-11-01 20:44:25 +01:00
test fix tests on v0.10.40 2015-08-31 11:20:35 -03:00
.gitignore .gitignore 2015-05-06 17:52:49 +02:00
.travis.yml add travis config 2015-05-29 09:42:19 -03:00
CHANGELOG.md update changelo 2015-05-17 22:06:10 -03:00
LICENSE.md add license, close #2 2014-03-14 20:31:04 -03:00
package.json 4.3.2 2015-10-13 13:57:38 -03:00
README.md minor. closes #43 2015-05-29 09:49:31 -03:00

Build Status

Authenticate socket.io incoming connections with JWTs. This is useful if you are build a single page application and you are not using cookies as explained in this blog post: Cookies vs Tokens. Getting auth right with Angular.JS.

Installation

npm install socketio-jwt

Example usage

// set authorization for socket.io
io.sockets
  .on('connection', socketioJwt.authorize({
    secret: 'your secret or public key',
    timeout: 15000 // 15 seconds to send the authentication message
  })).on('authenticated', function(socket) {
    //this socket is authenticated, we are good to handle more events from it.
    console.log('hello! ' + socket.decoded_token.name);
  });

Note: If you are using a base64-encoded secret (e.g. your Auth0 secret key), you need to convert it to a Buffer: Buffer('your secret key', 'base64')

Client side:

var socket = io.connect('http://localhost:9000');
socket.on('connect', function (socket) {
  socket
    .on('authenticated', function () {
      //do other things
    })
    .emit('authenticate', {token: jwt}); //send the jwt
});

One roundtrip

The previous approach uses a second roundtrip to send the jwt, there is a way you can authenticate on the handshake by sending the JWT as a query string, the caveat is that intermediary HTTP servers can log the url.

var io            = require("socket.io")(server);
var socketioJwt   = require("socketio-jwt");

//// With socket.io < 1.0 ////
io.set('authorization', socketioJwt.authorize({
  secret: 'your secret or public key',
  handshake: true
}));
//////////////////////////////

//// With socket.io >= 1.0 ////
io.use(socketioJwt.authorize({
  secret: 'your secret or public key',
  handshake: true
}));
///////////////////////////////

io.on('connection', function (socket) {
  // in socket.io < 1.0
  console.log('hello!', socket.handshake.decoded_token.name);

  // in socket.io 1.0
  console.log('hello! ', socket.decoded_token.name);
})

For more validation options see auth0/jsonwebtoken.

Client side:

Append the jwt token using query string:

var socket = io.connect('http://localhost:9000', {
  'query': 'token=' + your_jwt
});

Handling token expiration

Server side:

When you sign the token with an expiration time:

var token = jwt.sign(user_profile, jwt_secret, {expiresInMinutes: 60});

Your client-side code should handle it as below.

Client side:

socket.on("error", function(error) {
  if (error.type == "UnauthorizedError" || error.code == "invalid_token") {
    // redirect user to login page perhaps?
    console.log("User's token has expired");
  }
});

Contribute

You are always welcome to open an issue or provide a pull-request!

Also check out the unit tests:

npm test

License

Licensed under the MIT-License. 2013 AUTH10 LLC.