web-dev-qa-db-fra.com

Envoyer des données personnalisées avec handshakeData dans socket.io?

J'ai donc une application qui exécute le noeud js avec socket.io comme serveur principal et javascript normal comme serveur principal. Mon application dispose d’un système de connexion qui demande au client d’envoyer ses données de connexion dès qu’il est connecté.

Maintenant, je me suis dit qu'il serait bien plus agréable d'envoyer les données de connexion avec les données de transfert, afin que je puisse directement que l'utilisateur soit connecté lors de la connexion (au lieu d'établir une connexion) et refuser l'autorisation respectivement lorsque les données de connexion sont invalides.

Je pense qu'il serait préférable de mettre mes données supplémentaires dans la partie en-tête de la poignée de main, donc des idées pour que je puisse le faire? (Sans avoir à modifier socket.io si possible, mais si c'est le seul moyen de vivre avec cela)

53
Wingblade

Comme beaucoup de commentaires l'ont souligné ci-dessous, l'API Socket.IO a été modifiée dans la version 1.0. L'authentification doit maintenant être effectuée via une fonction middleware, voir 'Différences d'authentification' @ http://socket.io/docs/migrating-from-0-9/#authentication-differences . Je vais inclure ma réponse originale à toute personne bloquée sur <1.0, car les anciens documents semblent avoir disparu.

1.0 et plus tard:

Côté client:

//The query member of the options object is passed to the server on connection and parsed as a CGI style Querystring.
var socket = io("http://127.0.0.1:3000/", { query: "foo=bar" });

Du côté serveur:

io.use(function(socket, next){
    console.log("Query: ", socket.handshake.query);
    // return the result of next() to accept the connection.
    if (socket.handshake.query.foo == "bar") {
        return next();
    }
    // call next() with an Error if you need to reject the connection.
    next(new Error('Authentication error'));
});

Pré 1.0

Vous pouvez passer une requête: param dans le deuxième argument à connecter () côté client qui sera disponible sur le serveur dans la méthode d'autorisation. 

Je viens de le tester. Sur le client j'ai:

var c = io.connect('http://127.0.0.1:3000/', { query: "foo=bar" });

Sur le serveur:

io.set('authorization', function (handshakeData, cb) {
    console.log('Auth: ', handshakeData.query);
    cb(null, true);
});

La sortie sur le serveur ressemblait alors à:

:!node node_app/main.js
   info  - socket.io started
Auth:  { foo: 'bar', t: '1355859917678' }
134
Alex Wright

Cela a maintenant été changé dans la v1.0.0. Voir le docs de migration

fondamentalement,

io.set('authorization', function (handshakeData, callback) {
  // make sure the handshake data looks good
  callback(null, true); // error first, 'authorized' boolean second 
});

devient :

  io.use(function(socket, next) {
  var handshakeData = socket.request;
  // make sure the handshake data looks good as before
  // if error do this:
    // next(new Error('not authorized');
  // else just call next
  next();
});
19
slupek2013

Pour socket.io v1.2.1, utilisez ceci:

io.use(function (socket, next) {
  var handshake = socket.handshake;
  console.log(handshake.query);
  next();
});
10
zaynetro

Ceci est mon code pour l'envoi de données de requête au client serveur nodejs et server.io.

var socket = io.connect(window.location.Origin, { query: 'loggeduser=user1' });

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " + socket.manager.handshaken[socket.id].query.user);
}
7
user2969994

L'API a peut-être changé, mais j'ai procédé comme suit pour obtenir des informations supplémentaires sur le serveur.

// client
io.connect('localhost:8080', { query: 'foo=bar', extra: 'extra'});

// server
io.use(function(sock, next) {
  var handshakeData = sock.request;
  console.log('_query:', handshakeData._query);
  console.log('extra:', handshakeData.extra);
  next();
});

empreintes

_query: { foo: 'bar',
  EIO: '3',
  transport: 'polling',
  t: '1424932455409-0' }
extra: undefined

Si quelqu'un sait comment obtenir des données d'un client sur le serveur via la poignée de main ce n'est pas dans les paramètres de requête laissez-moi savoir s'il vous plaît.

Mise à jour J'ai rencontré des problèmes ultérieurement avec cette syntaxe.

io.connect('localhost:8080?foo=bar');

est ce que j'utilise actuellement.

1
Harry Moreno

J'ai trouvé un petit problème pour voir le .loggeduser

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " + socket.manager.handshaken[socket.id].query.loggeduser);
                                                                         // ↑ here
}
0
user3678015

Ancien fil, mais en supposant que vous stockiez votre identifiant de jeton/session dans des cookies de session (éléments standard), celui-ci est toujours transmis au serveur par défaut lors de la prise de contact (socket.io-client), j'ai remarqué .. avec juste obtenir les informations d'authentification pour la poignée de main (via middleware ou on.connection) via un cookie?

io.on('connection', function(socket) {
  // assuming base64url token
  const cookieStr = socket.handshake.headers.cookie
  const matchRes =
    cookieStr == null
      ? false
      : cookieStr.match(/my-auth-token=([a-zA-Z0-9_.-]+)/)
  if (matchRes) {
    // verify your jwt...
    if ( tokenIsGood(matchRes[1]) {
      // handle authenticated new socket
    } else {
      socket.emit('AUTH_ERR_LOGOUT')
      socket.disconnect()
    }
  } else {
    socket.emit('AUTH_ERR_LOGOUT')
    socket.disconnect()
  }
}

Je l'utilise maintenant pour un projet et cela fonctionne bien.

0
KM3