socket.io ve oturum?


96

Ekspres çerçeve kullanıyorum. Socket.io'dan oturum verilerine ulaşmak istiyorum. Client.listener.server.dynamicViewHelpers verileriyle dynamicHelpers'ı ifade etmeyi denedim, ancak oturum verilerini alamıyorum. Bunu yapmanın kolay bir yolu var mı? Lütfen koda bakın

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

5
Ya da bu ÇOK GÜZEL yazı kullanabilir: danielbaulig.de/socket-ioexpress
Fabiano Soriani

3
@FabianoPS - artık çalışmayacak - connect artık bunun dayandığı parseCookie yöntemini sağlamıyor.
UpTheCreek

1
@UpTheCreek - Connect artık parseCookie yöntemini kullanmadığına göre, bu nasıl mümkün olabilir?
Aust

@Aust - Güzel soru, şu anda en iyi yaklaşımın ne olduğunu bilmiyorum. Bu gerçekten karmakarışık bir IMO. Can sıkıcı bir şekilde, geçici çözüm tartışmalarının çoğu socket.io'ya da odaklanmıştır (herkes socket.io kullanmıyor!). Artık bir parseSignedCookie işlevi var, ancak bu da özeldir, bu nedenle değişiklikleri bozma riski de vardır.
UpTheCreek

2
Socket.IO (1.x) ve Express (4.x) 'in daha yeni sürümleri için şu SO sorusunu kontrol edin: stackoverflow.com/questions/25532692/…
pootzko

Yanıtlar:


68

Bu, flashsocket aktarımını aşan soketler için çalışmaz (sunucuya gerekli çerezleri göndermez) ancak diğer her şey için güvenilir bir şekilde çalışır. Kodumdaki flashsocket aktarımını devre dışı bıraktım.

Çalışmasını sağlamak için, ekspres / bağlantı tarafında, oturum deposunu açıkça tanımlıyorum, böylece onu soket içinde kullanabilirim:

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

Daha sonra soket kodumun içine, connect.sid'i çerezlerden almak için çerez ayrıştırmasını kullanabilmem için bağlantı çerçevesini ekliyorum. Daha sonra connect.sid'in bulunduğu oturum deposundaki oturuma şöyle bir bakarım:

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

Daha sonra oturumu gerektiği gibi kullanabilirsiniz.


3
Socket_client.request, socket.io-node'un son sürümlerinde kaldırılmış gibi görünüyor
Art

6
Dikkat edin ... Bunu şimdi yapmak için yeni kurallar var ... Onun yerine Socket.IO kimlik doğrulamasını kullanmanızı öneririm. @Jeffer
BMiner

2
Maalesef bu artık işe yaramayacak - parseCookie artık bağlantı araçlarının bir parçası değil. Görünüşe göre hiçbir zaman halka açık API'nin bir parçası değildi. Karmaşık bir alternatif var - parseSignedCookie, ama bu da özel, bu yüzden sanırım onun da ortadan kaybolma riski var ..
UpTheCreek

Şimdi bunu düşündüğüme göre .... neden sadece çerezler için mağaza ve soket için mağaza aynı mağazaya ayarlanmıyor?
James

34

Socket.IO-sessions modülü çözümü, istemci (komut dosyası oluşturma) düzeyinde oturum kimliğini açığa çıkararak uygulamayı XSS ​​saldırılarına maruz bırakır.

Bunun yerine bu çözümü kontrol edin (Socket.IO> = v0.7 için). Buradaki belgelere bakın .


1
@Jeffer - bu ikinci çözüm artık connect'in mevcut sürümüyle çalışmayacak.
UpTheCreek 01

2
-1 socket.io, oturum kimliğini açığa çıkaran şeydir, o modülü değil. Oturum kimliği istemci tarafında bir çerezde saklandığından bu çok önemli değil ... Ayrıca bu eğitim Express'in en son sürümü için çalışmıyor.
Aust

1
çözüm bağlantınız socket.iogithub sayfasına yönlendiriyor ..?
TJ


4

Düzenleme: Çalışmayan bazı modülleri denedikten sonra, bunu yapmak için aslında kendi kitaplığımı yazdım. Utanmaz eklenti: https://github.com/aviddiviner/Socket.IO-sessions adresinden kontrol edin . Eski yazımı aşağıda tarihsel amaçlarla bırakacağım:


Yukarıdaki pr0zac çözümüne göre flaş soket aktarımını atlamak zorunda kalmadan bu işi oldukça düzgün bir şekilde yaptım . Ayrıca Socket.IO ile express kullanıyorum. Nasıl yapacağınız burada.

İlk olarak, oturum kimliğini görünüme geçirin:

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

Ardından, görünümünüzde, Socket.IO istemci tarafına bağlayın:

<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'});"/>

Ardından sunucu tarafındaki Socket.IO dinleyicinizde, onu alın ve oturum verilerini okuyun / yazın:

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

Benim durumumda, kitaplığı session_storekullanan Redis'im redis-connect.

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

Umarım bu, Google'da arama yaparken bu gönderiyi bulan birine yardımcı olur (benim yaptığım gibi;)


8
Oturum kimliğinizi istemci
html'sine koymak

4
Oturum kimliği zaten yerel bir çerezde saklanmışken, oturum kimliğini HTML'ye koymak neden bu kadar kötü bir fikirdir?
Gavin

3
Çünkü tanımlama bilgileri, HttpOnly tanımlama bilgisi olarak ayarlandığında javascript'ten erişilemez. HTML'ye session.sid koyarak saldırgana DOM'da ihtiyaç duyduğu her şeyi verirsiniz.
rochal


2

Socket.IO-connect'e göz atın

Socket.IO-düğümü etrafında WebSocket Middleware Wrapper'ı bağlayın https://github.com/bnoguchi/Socket.IO-connect

Bu, Socket.IO isteklerini, Socket.IO olay işleyicileriyle işlemeden önce Express / Connect ara yazılım yığınını aşağı itmenize olanak tanıyarak size oturuma, tanımlama bilgilerine ve daha fazlasına erişim sağlar. Yine de, Socket.IO'nun tüm aktarımlarında çalıştığından emin değilim.


ne yazık ki bu modül hala socket.io v0.6'yı kullanıyor
48'de fent

2

Sen yararlanabilirler ekspres-socket.io oturum .

Çerez tabanlı hızlı oturum ara yazılımını socket.io ile paylaşın. Express> 4.0.0 ve socket.io> 1.0.0 ile çalışır ve geriye dönük uyumlu olmayacaktır.

Benim için çalıştı !!


Hey. Ön uçta oturum değerlerini nasıl kullanırsınız? Onları npm belgelerinde göremiyorum.
Hari Ram

1

Şuna bir göz atabilirsiniz: https://github.com/bmeck/session-web-sockets

veya alternatif olarak şunları kullanabilirsiniz:

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

Bu yardımcı olur umarım.


Oturum-web soketlerini biliyorum ama bunun için bir kitaplık kullanmak istemiyorum, basit bir çözüm arıyorum. Client.listener.server.viewHelpers'ı denedim; ancak şunu döndürdü: {}
sfs

2
bu ilk başta işe yarıyor gibi görünse de, yarış koşullarına yol açar. Tamamen kaçınmanızı öneririm.
Shripad Krishna

1

Doğru yaptığımdan emin değilim. https://github.com/LearnBoost/socket.io/wiki/Authorizing

El sıkışma verileri ile çerezlere erişebilirsiniz. Çerezlerde, her istemcinin oturum kimliği olan connect.sid'i yakalayabilirsiniz. Ve sonra oturum verilerini veritabanından almak için connect.sid kullanın (RedisStore kullandığınızı varsayıyorum)


bu tam olarak gitmek için bir yoldur, ancak havalı değilsiniz, böylece yığın taşma noktaları elde edemezsiniz. github.com/tcr/socket.io-session ve github.com/functioncallback/session.socket.io İlkini biraz daha temizleyici olarak seviyorum. İkincisi biraz daha iyi belgelenmiştir.
James

@TJ Bunun için üzgünüm ama cevabın 2 yıl önce olduğunun farkında mısınız? Ve muhtemelen şimdi işe yaramayacak
Tan Nguyen

@TanNguyen Biliyorum, bu yüzden insanları ölü bağlantılara yönlendirmek yerine yanıtı zorunlu olarak güncelleyebilmeniz için sizi bilgilendirdim
TJ

@TJ Bunun için teşekkür ederim. Maalesef 2 yıl önce performans sorunu nedeniyle socket.io'dan uzaklaştım. Bu nedenle, socket.io'daki oturumla başa çıkmanın şu anki yolu nedir bilmiyorum
Tan Nguyen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.