2012-12-03 20 views
9

में सत्र आईडी से अलग है मुझे दिए गए उदाहरण का उपयोग करके एक समान समस्या है। उदाहरण में, सत्र यह पहली बार पुन: लोड करके WebSocket में प्रयोग किया जाता है:एक्सप्रेस सत्र आईडी कुकी

socket.on('set value', function (val) { 
    sess.reload(function() { 
     sess.value = val; 
     sess.touch().save(); 
    }); 
    }); 

मेरे अपने आवेदन में इसका इस्तेमाल करने की कोशिश कर रहा है, मैं निम्न अपवाद प्राप्त करें:

sess.reload(function() { 
    ^
TypeError: Object #<Object> has no method 'reload' 

मैं इस समस्या लगता है यह है कि कोई भी वैरिएबल सेस को सत्र के रूप में परिभाषित नहीं करता है:

io.listen(app).set('authorization', function (data, accept) { 
    if (!data.headers.cookie) 
    return accept('No cookie transmitted.', false); 

    data.cookie = parseCookie(data.headers.cookie); 
    data.sessionID = data.cookie['express.sid']; 

    store.load(data.sessionID, function (err, session) { 
    if (err || !session) return accept('Error', false); 

    data.session = session; 
    return accept(null, true); 
    }); 
}) 

शायद कुछ के लिए इसका कोई छोटा फिक्स है?

समस्या हल: एक्सप्रेस 3.0 और Redis साथ https://github.com/DanielBaulig/sioe-demo/blob/master/app.js: मैं इस उदाहरण का उपयोग करने की कोशिश की।

इसलिए मैं एक Redis स्टोर बनाया (कनेक्ट-redis) एक MemoryStore के बजाय:

app.use(express.session({cookie: {expires: new Date(Date.now() + 30*60*60*24*1000)}, secret: SESSION_SECRET, key: SESSION_KEY, store: new RedisStore({host:'localhost', port:'6379', client: dbRedis})})); 

के बाद से कनेक्ट में parseCookie-विधि मैं

parseCookie = require('cookie').parse 
बजाय

इस्तेमाल किया ले जाया गया
connect.utils.parseCookie 

कुकी में सत्र तक पहुंचने के लिए मैंने उदाहरण को संशोधित किया का उपयोग करते हुए निम्नलिखित:

sio.set('authorization', function (data, accept) { 
    if (!data.headers.cookie) 
    return accept('No cookie transmitted.', false); 

    data.cookie = parseCookie(data.headers.cookie); 
    log.info('Cookie: $s', JSON.stringify(data.cookie)); 
    data.sessionID = data.cookie['letter.sid']; 
    log.info('SessionId: %s', data.sessionID); 

    dbRedis.get(data.sessionID, function (err, session) { 
    if (err || !session) return accept('Error ' + session, false); 

    data.session = session; 
    return accept(null, true); 
    }); 
}) 

अब मेरी समस्या यह है कि मैं क्योंकि सत्र आईडी अलग एक पृष्ठ (req.sessionID) मैं पाने पर सत्र आईडी मुद्रण नहीं कर सकते Redis से सत्र लोड: n + 57bnkLr + iXkMLbStWdFzK5 लेकिन Redis में निम्नलिखित आईडी संग्रहित किया जाता है:

[2012-12-03T22:14:56.632Z] INFO: Postbox/78964 on capns-mba.local: Cookie: $s {"SQLiteManager_currentLangue":"4","connect.sid":"s:xvYdDm5C0MEIg53EG8JgqBnM.Tx8+PMKa570zk6qt9vmCjRz2p/LP/COyyqGSm+VKxww","letter.sid":"s:n+57bnkLr+iXkMLbStWdFzK5.XPHh1xXrK9D4cPfJ7HcHO11PKk8FXLg6fIRGaWb/+jI"} 
[2012-12-03T22:14:56.632Z] INFO: Postbox/78964 on capns-mba.local: SessionId: s:n+57bnkLr+iXkMLbStWdFzK5.XPHh1xXrK9D4cPfJ7HcHO11PKk8FXLg6fIRGaWb/+jI 

जाहिर req.sessionID SessionID कुकी/redis में बचाया का हिस्सा है - लेकिन क्यों? और सही सत्र आईडी कौन सा है?

+0

ठीक है समस्या यह है कि मुझे dbRedis.get() का उपयोग करके सत्र नहीं मिलता है। – Markus

उत्तर

15

session middleware (लाइन 267) से कोड के इस टुकड़े पर देखो:

var val = 's:' + signature.sign(req.sessionID, secret); 

जहां signature.sign समारोह एक संयोजन (छद्म कोड) है: (

req.sessionID + "." + hash(secret) 

जहां hash एक कस्टम समारोह है see this for more details)।

इसका मतलब है कि यह कुकीज़ के लिए केवल एक हस्ताक्षर सम्मेलन है (इसे और अधिक सुरक्षित बनाने के लिए)। आप कॉल करके अपने एसआईडी को पुनः प्राप्त कर सकते हैं:

var signature = require("cookie-signature"), 
    prefix = "s:"; 

var real_sid = sid.replace(prefix, ""); 
real_sid = signature.unsign(real_sid, SESSION_SECRET); 
+0

धन्यवाद मेरी समस्या पूरी तरह से हल की गई – Markus

+1

आपने इसका उत्तर देने के कुछ सालों बाद, आज आप एक व्यक्ति के जीवन को बचाया। धन्यवाद! :) – geevee

+0

मेरे मामले में मुझे sid = decodeURIComponent (sid) करना पड़ा; सबसे पहले, क्योंकि सत्र आईडी को कुकी में एन्कोडेड स्ट्रिंग में संग्रहीत किया जाता है। –

संबंधित मुद्दे