web-dev-qa-db-fra.com

socket.io et session?

J'utilise un cadre express. Je souhaite accéder aux données de session depuis socket.io. J'ai essayé d'exprimer dynamicHelpers avec les données client.listener.server.dynamicViewHelpers, mais je ne peux pas obtenir de données de session. Y a-t-il un moyen simple de faire cela? S'il vous plaît voir le code

app.listen(3000);

var io = require('socket.io');
var io = io.listen(app);

io.on('connection', function(client){
    // I want to use session data here
    client.on('message', function(message){
        // or here
    });
    client.on('disconnect', function(){
        // or here
    }); 
});
95
sfs

Cela ne fonctionnera pas pour les sockets utilisant le transport flashsocket (cela n'enverra pas les cookies nécessaires au serveur) mais cela fonctionnera de manière fiable pour tout le reste. Je viens de désactiver le transport flashsocket dans mon code.

Pour le faire fonctionner, du côté express/connect, je définis explicitement le magasin de session afin de pouvoir l'utiliser à l'intérieur du socket:

MemoryStore = require('connect/middleware/session/memory'),
var session_store = new MemoryStore();
app.configure(function () {
  app.use(express.session({ store: session_store }));
});

Ensuite, dans mon code de socket, j'inclus le framework de connexion afin que je puisse utiliser son analyse de cookie pour récupérer le connect.sid à partir des cookies. Je cherche alors la session dans le magasin de session qui a ce connect.sid comme ceci:

var connect = require('connect');
io.on('connection', function(socket_client) {
  var cookie_string = socket_client.request.headers.cookie;
  var parsed_cookies = connect.utils.parseCookie(cookie_string);
  var connect_sid = parsed_cookies['connect.sid'];
  if (connect_sid) {
    session_store.get(connect_sid, function (error, session) {
      //HOORAY NOW YOU'VE GOT THE SESSION OBJECT!!!!
    });
  }
});

Vous pouvez ensuite utiliser la session si nécessaire.

69
pr0zac

La solution de module Socket.IO-sessions expose l'application aux attaques XSS en exposant l'ID de session au niveau du client (script).

Cochez plutôt solution (pour Socket.IO> = v0.7). Voir docs ici .

34
Jeffer

Je suggère de ne pas réinventer entièrement la roue. Les outils dont vous avez besoin sont déjà un package npm.Je pense que c’est ce dont vous avez besoin: session.socket.io Je l’utilise de nos jours et il sera très utile je suppose !! Lier la session express à la couche socket.io aura de nombreux avantages!

8
Francesco

Edit: Après avoir essayé des modules qui ne fonctionnaient pas, je suis allé écrire ma propre bibliothèque pour le faire. Fiche éhontée: allez voir à https://github.com/aviddiviner/Socket.IO-sessions . Je vais laisser mon ancien message ci-dessous à des fins historiques:


J'ai eu ce travail assez proprement sans avoir à contourner le flashsocket transport selon la solution de pr0zac ci-dessus. J'utilise aussi express avec Socket.IO. Voici comment.

Tout d'abord, passez l'ID de session à la vue:

app.get('/', function(req,res){
  res.render('index.ejs', {
    locals: { 
      connect_sid: req.sessionID
      // ...
    }
  });
});

Ensuite, à votre avis, associez-le au côté client Socket.IO:

<script>
  var sid = '<%= connect_sid %>';
  var socket = new io.Socket();
  socket.connect();
</script>
<input type="button" value="Ping" onclick="socket.send({sid:sid, msg:'ping'});"/>

Ensuite, dans votre programme d'écoute Socket.IO côté serveur, récupérez-le et lisez/écrivez les données de la session:

var socket = io.listen(app);
socket.on('connection', function(client){
  client.on('message', function(message){
    session_store.get(message.sid, function(error, session){
      session.pings = session.pings + 1 || 1;
      client.send("You have made " + session.pings + " pings.");
      session_store.set(message.sid, session);  // Save the session
    });
  });
});

Dans mon cas, mon session_store est Redis, en utilisant le redis-connect bibliothèque.

var RedisStore = require('connect-redis');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));

J'espère que cela aidera quelqu'un qui trouvera ce post en cherchant sur Google (comme je l'ai fait;)

4
Dave

Voir ceci: authentification Socket.IO

Je suggère de ne rien chercher via client.request... ou client.listener... car cela n’est pas directement lié à l’objet client et pointe toujours vers le dernier utilisateur connecté!

3
Shripad Krishna

Vous pouvez utiliser express-socket.io-session .

Partagez un middleware de session express basé sur des cookies avec socket.io. Fonctionne avec express> 4.0.0 et socket.io> 1.0.0 et ne sera pas compatible avec les versions antérieures.

Travaillé pour moi !!

2
nonybrighto

Découvrez Socket.IO-connect

Connecter le WebSocket Middleware Wrapper autour du noeud Socket.IO https://github.com/bnoguchi/Socket.IO-connect

Cela vous permettra de rejeter la ou les requêtes Socket.IO vers le bas dans la pile de middleware Express/Connect avant de la traiter avec les gestionnaires d'événements Socket.IO, ce qui vous donnera accès à la session, aux cookies, etc. Bien que, je ne suis pas sûr que cela fonctionne avec tous les transports de Socket.IO.

2
BMiner

Vous pouvez consulter ceci: https://github.com/bmeck/session-web-sockets

ou bien vous pouvez utiliser:

io.on('connection', function(client) { 
  var session = client.listener.server.viewHelpers; 
  // use session here 
});

J'espère que cela t'aides.

1
intellidiot

Je ne suis pas sûr de bien faire les choses. https://github.com/LearnBoost/socket.io/wiki/Authorizing

Avec les données de négociation, vous pouvez accéder aux cookies. Et dans les cookies, vous pouvez récupérer connect.sid, qui est l'identifiant de session de chaque client. Et utilisez ensuite connect.sid pour obtenir les données de session de la base de données (je suppose que vous utilisez RedisStore)

1
Tan Nguyen