2012-12-03 30 views
9

Tôi gặp vấn đề tương ứng bằng cách sử dụng ví dụ đã cho. Trong ví dụ này, phiên giao dịch được sử dụng trong WebSocket bằng tải lại nó lần đầu tiên:ExpressID phiên khác với SessionID trong Cookie

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

Cố gắng sử dụng nó trong ứng dụng của riêng tôi, tôi nhận được ngoại lệ sau đây:

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

Tôi nghĩ vấn đề là, không ai định nghĩa biến biến thành phiên:

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

Có thể một số sửa lỗi ngắn cho điều này?

Sự cố được giải quyết: Tôi đã cố sử dụng ví dụ này: https://github.com/DanielBaulig/sioe-demo/blob/master/app.js với Express 3.0 và Redis.

Do đó tôi tạo ra một cửa hàng Redis (kết nối-redis) thay vì một 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})})); 

Kể từ khi parseCookie-Phương pháp trong kết nối chuyển i sử dụng

parseCookie = require('cookie').parse 

thay vì

connect.utils.parseCookie 

Để truy cập phiên trong cookie, tôi đã sửa đổi ví dụ này theo sử dụng như sau:

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

Bây giờ vấn đề của tôi là, tôi không thể tải các phiên từ Redis vì các ID phiên khác nhau In ID phiên trên một trang (req.sessionID) tôi nhận được: n + 57bnkLr + iXkMLbStWdFzK5 nhưng trong Redis ID sau đây được lưu trữ:

[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 

Rõ ràng là req.sessionID là một phần của SessionID được lưu trong cookie/redis - nhưng tại sao? Và sessionID chính xác là gì?

+0

Ok vấn đề là tôi không có phiên bằng cách sử dụng dbRedis.get(). – Markus

Trả lời

15

Nhìn vào đoạn mã này từ session middleware (dòng 267):

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

nơi signature.sign chức năng là một nối (pseudo-code):

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

nơi hash là một chức năng tùy chỉnh (see this for more details).

Điều này có nghĩa rằng đây chỉ là quy ước ký cho cookie (để làm cho nó an toàn hơn). Bạn có thể truy xuất sid của mình bằng cách gọi:

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

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

Cảm ơn bạn đã giải quyết xong vấn đề của mình một cách hoàn hảo – Markus

+1

Vài năm sau khi bạn trả lời câu hỏi này, hôm nay, bạn đã cứu sống một người đàn ông. Cảm ơn bạn! :) – geevee

+0

Trong trường hợp của tôi, tôi phải làm sid = decodeURIComponent (sid); đầu tiên, vì ID phiên được lưu trữ trong chuỗi được mã hóa trong cookie. –

Các vấn đề liên quan