Authenticating socket io connections using JWT

How can I authenticate a socket.io connection? My application uses a login endpoint from another server (python) to get a token, how can I get use that token whenever a user opens a socket connection on the node side?

io.on('connection', function(socket) {
    socket.on('message', function(message) {
        io.emit('message', message);
    });
});

And the client side:

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

If the token is created in python:

token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')

How can I use this token to authenticate a socket connection in node?


It doesn't matter if the token was created on another server. You can still verify it if you have the right secret key and algorithm.

Implementation with jsonwebtoken module

client

const {token} = sessionStorage;
const socket = io.connect('http://localhost:3000', {
  query: {token}
});

Server

const io = require('socket.io')();
const jwt = require('jsonwebtoken');

io.use(function(socket, next){
  if (socket.handshake.query && socket.handshake.query.token){
    jwt.verify(socket.handshake.query.token, 'SECRET_KEY', function(err, decoded) {
      if (err) return next(new Error('Authentication error'));
      socket.decoded = decoded;
      next();
    });
  }
  else {
    next(new Error('Authentication error'));
  }    
})
.on('connection', function(socket) {
    // Connection now authenticated to receive further events

    socket.on('message', function(message) {
        io.emit('message', message);
    });
});

Implementation with socketio-jwt module

This module makes the authentication much easier in both client and server side. Just check out their examples.

client

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

Server

const io = require('socket.io')();
const socketioJwt = require('socketio-jwt');

io.sockets
  .on('connection', socketioJwt.authorize({
    secret: 'SECRET_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}`);
  });