100 votes

socket.io et session ?

J'utilise le framework express. Je veux atteindre les données de session à partir de socket.io. J'ai essayé express dynamicHelpers avec les données client.listener.server.dynamicViewHelpers, mais je n'arrive pas à obtenir les données de session. Existe-t-il un moyen simple de faire cela ? Veuillez 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
    }); 
});

6 votes

Ou peut utiliser ce TRES BON poste : danielbaulig.de/socket-ioexpress

3 votes

@FabianoPS - ne fonctionnera plus - connect ne fournit plus la méthode parseCookie sur laquelle cela repose.

1 votes

@UpTheCreek - Puisque connect n'utilise plus la méthode parseCookie, comment cela peut-il être possible ?

67voto

pr0zac Points 554

Cela ne fonctionnera pas pour les sockets passant par le transport flashsocket (cela n'envoie pas au serveur les cookies nécessaires) mais cela fonctionne de manière fiable pour tout le reste. Je désactive simplement le transport flashsocket dans mon code.

Pour que cela fonctionne, du côté express/connect, je définis explicitement le magasin de session afin de pouvoir l'utiliser dans le 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 connect afin de pouvoir utiliser son analyse des cookies pour récupérer le connect.sid des cookies. Je recherche alors la session dans le magasin de session qui a ce connect.sid comme suit :

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 selon vos besoins.

3 votes

Il semble que socket_client.request ait été supprimé dans les dernières versions de socket.io-node.

6 votes

Attention... il y a de nouvelles conventions pour faire cela maintenant... Je suggère d'utiliser l'authentification Socket.IO à la place. Voir le message de @Jeffer

2 votes

Malheureusement, cela ne fonctionnera plus - parseCookie ne fait plus partie de connect utils. Apparemment, il n'a jamais fait partie de l'api publique. Il y a une alternative désordonnée - parseSignedCookie, mais elle est aussi privée, donc je suppose qu'elle risque de disparaître aussi

34voto

Jeffer Points 369

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

Vérifiez ceci solution à la place (pour Socket.IO >= v0.7). Voir la documentation ici .

1 votes

@Jeffer - cette deuxième solution ne fonctionnera plus avec la version actuelle de connect.

2 votes

-1 socket.io est ce qui expose l'ID de session, pas ce module. Ce n'est pas un gros problème puisque l'ID de session est stocké côté client dans un cookie de toute façon... Ce tutoriel ne fonctionne pas non plus avec la dernière version d'Express.

2 votes

Le lien de votre solution redirige simplement vers socket.io page github ?

8voto

Francesco Points 46

Je vous suggère de ne pas réinventer entièrement la roue. L'outil dont vous avez besoin est déjà un paquet npm. Je pense que c'est ce dont vous avez besoin : session.socket.io Je l'utilise ces jours-ci et je pense qu'il me sera très utile ! Lier la session express à la couche socket.io aura tellement d'avantages !

6 votes

Voici un module mis à jour qui prend en charge socket.io-express-sessions pour socket.io >= 1.0 github.com/xpepermint/socket.io-express-session

4voto

Dave Points 1080

Edit : Après avoir essayé des modules qui n'ont pas fonctionné, j'ai écrit ma propre bibliothèque pour faire cela. Vous pouvez la consulter à l'adresse suivante https://github.com/aviddiviner/Socket.IO-sessions . Je laisse mon ancien message ci-dessous à des fins historiques :


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

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

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

Puis, dans votre vue, liez-la à Socket.IO côté client :

<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 écouteur 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 trouve cet article en cherchant sur Google (comme je l'ai fait ;)

9 votes

Mettre votre identifiant de session dans le html du client n'est pas une bonne idée du point de vue de la sécurité...

4 votes

Pourquoi mettre l'identifiant de session dans le HTML est une si mauvaise idée alors que l'identifiant de session est déjà stocké dans un cookie local ?

4 votes

Parce que les cookies ne peuvent pas être accédés à partir de javascript lorsqu'ils sont définis comme des cookies HttpOnly. En plaçant session.sid dans le HTML, vous donnez à l'attaquant tout ce dont il a besoin dans le DOM.

2voto

Shripad K Points 6594

Regardez ça : Authentification Socket.IO

Je suggère de ne rien récupérer via client.request... ou client.listener... car elle n'est pas directement liée à la client et pointe toujours vers le dernier utilisateur connecté !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X