Аутентифікація з'єднань socket 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')

Як я можу використовувати цей маркер для автентифікації з'єднання сокета у вузлі?

Відповіді:


226

Не має значення, чи маркер був створений на іншому сервері. Ви все ще можете перевірити це, якщо у вас є правильний секретний ключ та алгоритм.

Реалізація за допомогою 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}`);
  });

Я стикаюся з проблемою, хоча до вхідного підключення до сокета немає вхідного зв'язку, коли я запустив сервер сокетів, він все ще має старий маркер. це дивно?
Ламур

Які доступні варіанти з 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
Слід зазначити, що ви пишете швидку мову. Інші люди просто цього не знають.
Меч Джейсон

6
Вам потрібно пояснити цю відповідь, інакше це корисно не для всіх. Також якщо це написано швидкою мовою, будь ласка, згадайте це у своїй відповіді
Фредді Даніель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.