Authentifizieren von Socket-Io-Verbindungen mit JWT

97

Wie kann ich eine socket.io-Verbindung authentifizieren? Meine Anwendung verwendet einen Anmeldeendpunkt von einem anderen Server (Python), um ein Token abzurufen. Wie kann ich dieses Token verwenden, wenn ein Benutzer eine Socket-Verbindung auf der Knotenseite öffnet?

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

Und die Kundenseite:

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

Wenn das Token in Python erstellt wird:

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

Wie kann ich dieses Token verwenden, um eine Socket-Verbindung im Knoten zu authentifizieren?

el_pup_le
quelle

Antworten:

210

Es spielt keine Rolle, ob das Token auf einem anderen Server erstellt wurde. Sie können es weiterhin überprüfen, wenn Sie den richtigen geheimen Schlüssel und Algorithmus haben.

Implementierung mit jsonwebtokenModul

Klient

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

Implementierung mit socketio-jwtModul

Dieses Modul erleichtert die Authentifizierung sowohl auf Client- als auch auf Serverseite erheblich. Schauen Sie sich einfach ihre Beispiele an.

Klient

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}`);
  });
Hassansin
quelle
Ich habe ein Problem, obwohl keine eingehende Verbindung zum Socket besteht. Wenn ich den Socket-Server hochgefahren habe, hat er immer noch das alte Token. Ist das komisch ?
Lamour
Was sind die verfügbaren Optionen mit io.connect in Client API
Rocketspacer
2
Wie würden Sie die Verbindung zum Server wiederherstellen, falls der Benutzer ursprünglich nicht autorisiert war und beim ersten Versuch kein Geheimnis hatte?
Sznrbrt
9
Hallo, ich muss fragen, Token wird einmalig bei der Verbindung oder bei jedem emittierenden Ereignis benötigt?
Krunal Limbad
2
Für jeden, der etwas bekommt Cannot read property 'on' of undefined; Entfernen Sie einfach die socketaus function(socket).
Thomas Orlita
-25

Sie können diese URL verwenden.

var socket = SocketIOClient(socketURL: URL(string: "http://00.00.00.00:port")!, config: SocketIOClientConfiguration(arrayLiteral: SocketIOClientOption.connectParams(["token": "your secret key"])))
Vikash Sharma
quelle
9
Sie sollten angeben, dass Sie eine schnelle Sprache schreiben. Andere Leute wissen das einfach nicht.
Schwert Jason
5
Sie müssen diese Antwort erklären, sonst ist dies nicht für alle nützlich. Auch wenn es in schneller Sprache geschrieben ist, erwähnen Sie dies bitte in Ihrer Antwort
Freddy Daniel