Аутентификация соединений сокета io с помощью JWT

106

Как я могу аутентифицировать соединение socket.io? Мое приложение использует конечную точку входа с другого сервера (python) для получения токена, как я могу использовать этот токен всякий раз, когда пользователь открывает соединение сокета на стороне узла?

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

И на стороне клиента:

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

Если токен создан на python:

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

Как я могу использовать этот токен для аутентификации сокета в узле?

el_pup_le
источник

Ответы:

227

Не имеет значения, был ли токен создан на другом сервере. Вы все равно можете проверить это, если у вас есть правильный секретный ключ и алгоритм.

Реализация с jsonwebtokenмодулем

клиент

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

Сервер

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);
    });
});

Реализация с socketio-jwtмодулем

Этот модуль значительно упрощает аутентификацию как на стороне клиента, так и на стороне сервера. Просто посмотрите их примеры.

клиент

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
});

Сервер

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}`);
  });
хассансин
источник
Я столкнулся с проблемой, хотя входящего подключения к сокету нет, но когда я запустил сервер сокета, у него все еще есть старый токен. это странно?
Lamour
Какие доступны варианты с io.connect в клиентском api
rocketspacer
2
Как бы вы повторно подключились к серверу, если пользователь был изначально неавторизованным и у него не было секрета с первой попытки?
sznrbrt
9
привет, мне нужно спросить, токен требуется один раз при соединении или при каждом излучающем событии?
Крунал Лимбад
2
Для всех, кто получает Cannot read property 'on' of undefined; просто удалите socketиз function(socket).
Томас Орлита,
-28

вы можете использовать этот URL.

var socket = SocketIOClient(socketURL: URL(string: "http://00.00.00.00:port")!, config: SocketIOClientConfiguration(arrayLiteral: SocketIOClientOption.connectParams(["token": "your secret key"])))
Викаш Шарма
источник
9
Вы должны заявить, что пишете на быстром языке. Другие просто этого не знают.
Sword Jason
6
Вам необходимо объяснить этот ответ, иначе он пригодится не всем. Также, если это написано быстрым языком, пожалуйста, укажите это в своем ответе
Фредди Дэниел