socket.io और सत्र?


95

मैं एक्सप्रेस फ्रेमवर्क का उपयोग कर रहा हूं। मैं socket.io से सत्र डेटा तक पहुंचना चाहता हूं। मैंने client.listener.server.dynamicViewHelpers डेटा के साथ डायनामिक हेल्पर्स व्यक्त करने की कोशिश की, लेकिन मैं सत्र डेटा नहीं दे सकता। क्या ऐसा करने के लिए एक सरल तरीका है? कृपया कोड देखें

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
या इस बहुत अच्छे पद का उपयोग कर सकते हैं: danielbaulig.de/socket-ioexpress
Fabiano Soriani

3
@FabianoPS - अब और काम नहीं करेगा - कनेक्ट अब उस पार्सकुइकी विधि को प्रदान नहीं करता है जिस पर यह निर्भर करता है।
UpTheCreek

1
@UpTheCreek - चूंकि कनेक्ट अब पार्सकेसी पद्धति का उपयोग नहीं करता है, यह कैसे संभव हो सकता है?
ऑस्ट

@ बस - अच्छा सवाल, मुझे नहीं पता कि अब सबसे अच्छा तरीका क्या है। यह वास्तव में एक गड़बड़ IMO है। आमतौर पर वर्कअराउंड की अधिकांश चर्चाएं सॉकेट.आईओ (सभी लोग सॉकेट.आईओ का उपयोग नहीं करते हैं) पर भी जमकर की जाती हैं। अब एक parseSignCookie फ़ंक्शन है, लेकिन यह निजी भी है, इसलिए इसके टूटने का भी खतरा है।
UpTheCreek

2
सॉकेट.आईओ (1.x) और एक्सप्रेस (4.x) के नए संस्करणों के लिए इस SO प्रश्न की जाँच करें: stackoverflow.com/questions/25532692/…
pootzko

जवाबों:


68

यह फ़्लैशस्कैट ट्रांसपोर्ट पर जाने वाले सॉकेट्स के लिए काम नहीं करेगा (यह सर्वर को आवश्यक कुकीज़ नहीं भेजता है), लेकिन यह मज़बूती से हर चीज के लिए काम करता है। मैं बस अपने कोड में फ्लैशस्कैट परिवहन को अक्षम करता हूं।

इसे काम करने के लिए, एक्सप्रेस / कनेक्ट साइड में, मैं सत्र स्टोर को स्पष्ट रूप से परिभाषित करता हूं ताकि मैं इसे सॉकेट के अंदर उपयोग कर सकूं:

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

फिर मेरे सॉकेट कोड के अंदर, मैं कनेक्ट फ्रेमवर्क शामिल करता हूं ताकि मैं कुकी से पार्सिंग को जोड़ने के लिए इसकी कुकी पार्सिंग का उपयोग कर सकूं। मैं तब सत्र स्टोर में सत्र देखता हूं जिसमें कनेक्ट है। ऐसा करने के लिए:

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

फिर आप आवश्यकतानुसार सत्र का उपयोग कर सकते हैं।


3
ऐसा लगता है कि socket_client.request को socket.io-node
Art

6
खबरदार ... अब ऐसा करने के लिए नए सम्मेलन हैं ... मैं इसके बजाय सॉकेट.आईओ प्रमाणीकरण का उपयोग करने का सुझाव दूंगा। @ जेफर से पोस्ट देखें
बीएमएनआर

2
दुर्भाग्य से यह अभ्यस्त कोई और काम करता है - parseCookie अब कनेक्ट बर्तनों का हिस्सा नहीं है। जाहिर तौर पर यह सार्वजनिक एप का हिस्सा नहीं था। वहाँ एक गंदा विकल्प है - parseSignedCookie, लेकिन यह भी निजी है, इसलिए मैं .. गायब होने का खतरा होता है इसका अनुमान भी
UpTheCreek

अब जब मैं इस बारे में सोच रहा हूं .... क्यों न सिर्फ कुकीज़ के लिए स्टोर और सॉकेट के लिए स्टोर को उसी स्टोर में सेट किया जाए?
जेम्स

34

सॉकेट.आईओ-सत्र मॉड्यूल समाधान क्लाइंट (स्क्रिप्टिंग) स्तर पर सत्र आईडी को उजागर करके XSS हमलों के लिए ऐप को उजागर करता है।

इसके बजाय इस समाधान की जाँच करें (सॉकेट के लिए ।IO> = v0.7)। यहां डॉक्स देखें ।


1
@ जेफर - कनेक्ट के वर्तमान संस्करण के साथ वह दूसरा समाधान अब काम नहीं करेगा।
UpTheCric

2
-1 socket.ioवह है जो सत्र आईडी को उजागर कर रहा है, उस मॉड्यूल को नहीं। यह एक बड़ी बात नहीं है क्योंकि कुकी आईडी में सेशन आईडी क्लाइंट-साइड स्टोर की जाती है ... यह भी कि ट्यूटोरियल एक्सप्रेस के नवीनतम संस्करण के लिए काम नहीं करता है।
ऑस्ट

1
आपका समाधान लिंक केवल socket.ioजीथूब पृष्ठ पर पुनर्निर्देशित करता है ..?
TJ

8

मेरा सुझाव है कि पहिया को पूरी तरह से मजबूत न करें। आपके लिए आवश्यक उपकरण पहले से ही एक npm पैकेज है। मुझे लगता है कि यह वही है जो आपको चाहिए: session.socket.io मैं इन दिनों में इसका उपयोग कर रहा हूं और यह बहुत उपयोगी होगा मुझे लगता है !! एक्सप्रेस-सेशन को सॉकेट से लिंक करने पर ।io लेयर के इतने फायदे होंगे!


6
यहाँ एक अद्यतन मॉड्यूल का समर्थन करता है socket.io-व्यक्त-सत्र socket.io> = 1.0 के लिए है github.com/xpepermint/socket.io-express-session
blnc

4

संपादित करें: कुछ मॉड्यूल की कोशिश करने के बाद जो काम नहीं किया, मैं वास्तव में चला गया और ऐसा करने के लिए अपनी खुद की लाइब्रेरी लिखी। बेशर्म प्लग: इसे https://github.com/aviddiviner/Socket.IO-session पर देखें । मैं ऐतिहासिक उद्देश्यों के लिए अपनी पुरानी पोस्ट नीचे छोड़ दूंगा:


मुझे यह काम काफी साफ- सुथरा मिला है, बिना फ्लैशस्कैकेट ट्रांसपोर्ट को प्रोजैक के ऊपर दिए गए समाधान के अनुसार। मैं Socket.IO के साथ एक्सप्रेस का भी उपयोग कर रहा हूं। ऐसे।

सबसे पहले, दृश्य को सत्र आईडी पास करें:

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

फिर आपके विचार में, इसे सॉकेट.आईओ क्लाइंट-साइड के साथ लिंक करें:

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

फिर अपने सर्वर साइड सॉकेट.आईओ श्रोता में, इसे चुनें और सत्र डेटा पढ़ें / लिखें:

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

मेरे मामले में, लाइब्रेरी session_storeका उपयोग करते हुए , मेरा रेडिस है redis-connect

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

आशा है कि यह Google को खोजते समय किसी ऐसे व्यक्ति की मदद करता है (जैसा मैंने किया;)


8
क्लाइंट सत्र में अपना सेशन आईडी डाल देना सुरक्षा के नजरिए से अच्छा विचार नहीं है ...
UpTheCreek

4
HTML में सेशन आईडी को ऐसे बुरे विचार में क्यों रखा जाता है जब सत्र आईडी पहले ही एक स्थानीय कुकी में संग्रहीत हो जाती है?
गेविन

3
क्योंकि कुकीज़ को जावास्क्रिप्ट से एक्सेस नहीं किया जा सकता है जब HttpOnly कुकी के रूप में सेट किया जाता है। HTML में session.sid लगाकर आप हमलावर को वह सब कुछ देते हैं जो उन्हें DOM में चाहिए होता है।
रोचेल

3

इसे देखें: सॉकेट.आईओ प्रमाणीकरण

मैं सुझाव दूंगा कि किसी भी चीज के माध्यम से client.request...या client.listener...जैसा कि सीधे clientवस्तु से जुड़ा नहीं है और हमेशा अंतिम लॉग इन करने वाले को इंगित करता है!


2

Socket.IO- कनेक्ट की जाँच करें

सॉकेट के चारों ओर WebSocket मिडलवेयर रैपर कनेक्ट करें।

यह आपको Socket.IO घटना संचालकों के साथ इसे संभालने से पहले, एक्सप्रेस / कनेक्ट मिडलवेयर स्टैक के नीचे Socket.IO अनुरोध (ओं) को धकेलने की अनुमति देगा, जिससे आपको सत्र, कुकीज़ और अधिक तक पहुंच प्राप्त होगी। हालाँकि, मुझे यकीन नहीं है कि यह Socket.IO के सभी ट्रांसपोर्ट के साथ काम करता है।


दुर्भाग्य से मॉड्यूल अभी भी socket.io की v0.6 उपयोग कर रहा है कि
fent

2

आप एक्सप्रेस-सॉकेट.आईओ-सत्र का उपयोग कर सकते हैं ।

सॉकेट के साथ कुकी-आधारित एक्सप्रेस-सत्र मिडलवेयर साझा करें। एक्सप्रेस> 4.0.0 और सॉकेट .io> 1.0.0 के साथ काम करता है और यह बैकवर्ड संगत नहीं होगा।

मेरे लिए काम किया !!


अरे। आप सत्र-मानों का उपयोग फ्रंट-एंड में कैसे करेंगे? मैं उन्हें npm डॉक्स में नहीं देख सकता।
हरि राम

1

आप इस पर एक नज़र डाल सकते हैं: https://github.com/bmeck/session-web-sockets

या वैकल्पिक रूप से आप उपयोग कर सकते हैं:

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

उम्मीद है की यह मदद करेगा।


मैं सत्र-वेब-सॉकेट जानता हूं, लेकिन मैं इसके लिए एक पुस्तकालय का उपयोग नहीं करना चाहता, मैं एक सरल समाधान की तलाश कर रहा हूं। मैंने क्लाइंट की कोशिश की। लेकिन इसने यह लौटा दिया: {}
sfs

2
हालांकि यह पहली बार में काम करने लगता है, यह दौड़ की स्थिति की ओर जाता है। मेरा सुझाव है कि आप इसे पूरी तरह से टालें।
श्रीपद कृष्ण

1

मुझे यकीन नहीं है कि मैं इसे सही कर रहा हूं। https://github.com/LearnBoost/socket.io/wiki/Authorizing

हैंडशेक डेटा के साथ, आप कुकीज़ तक पहुंच सकते हैं। और कुकीज़ में, आप connect.sid को पकड़ सकते हैं जो प्रत्येक क्लाइंट के लिए सत्र आईडी है। और फिर डेटाबेस से सत्र डेटा प्राप्त करने के लिए connect.sid का उपयोग करें (मुझे लगता है कि आप RedisStore का उपयोग कर रहे हैं)


यह बिल्कुल जाने का रास्ता है, लेकिन आपका ठंडा नहीं है इसलिए आप ढेर ओवरफ्लो पॉइंट नहीं ले सकते। github.com/tcr/socket.io-session और github.com/functioncallback/session.socket.io मैं पहली बार थोड़ा बेहतर अपने क्लीनर की तरह। दूसरा एक बेहतर दस्तावेज है।
जेम्स

@ टीजे मुझे इस बारे में खेद है लेकिन क्या आपको पता है कि उत्तर 2 साल पहले था? और यह शायद अब काम नहीं करेगा
टैन गुयेन

@TanNguyen मुझे पता है, इसीलिए मैंने आपको सूचित किया है ताकि आप लोगों को मृत लिंक की ओर इशारा करने की अपेक्षा उत्तर को अपडेट कर सकें
TJ

@TJ इसके लिए धन्यवाद। दुर्भाग्य से, मैं 2 साल पहले प्रदर्शन की समस्या के कारण सॉकेट से दूर चला गया। इसलिए, मुझे नहीं पता कि सॉकेट में सत्र से निपटने का वर्तमान तरीका क्या है।
तन गुयेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.