2012-08-31 43 views
3

當socket.io查找會話時,由於cookie的ID與數據庫中的ID不匹配,我得到握手錯誤。我正在使用Express3,mongodb,connect-mongodb和socket.io v0.9.10socket.io cookie解析握手錯誤

例如,包含在socket.io代碼中的console.log(data.sessionID)的結果將會打印出來:

s:eFFkUnQXWdTO7GBRDc11No/a.U6voj5QnxKs1skq766nO7/qJvPEJA73KaQM67qNEs/k

,但是當我在會議收集一下我的數據庫,我得到以下_id:

"_id" : "eFFkUnQXWdTO7GBRDc11No/a", 

正如你可以看到這相當於data.sessionID在S後:和在此期間之前。我嘗試使用兩個不同的cookie解析器。下面的解析器的代碼是來自包含在express 3中的cookie模塊。我不確定每個cookie ID是否遵循這個模式,所以我不知道我是否應該再次自己解析結果,或者如果有什麼我是做錯了。

exports.parseCookie = function(str) { 
var obj = {} 
var pairs = str.split(/[;,] */); 
var encode = encodeURIComponent; 
var decode = decodeURIComponent; 

pairs.forEach(function(pair) { 
    var eq_idx = pair.indexOf('=') 
    var key = pair.substr(0, eq_idx).trim() 
    var val = pair.substr(++eq_idx, pair.length).trim(); 

    // quoted values 
    if ('"' == val[0]) { 
     val = val.slice(1, -1); 
    } 

    // only assign once 
    if (undefined == obj[key]) { 
     obj[key] = decode(val); 
    } 
}); 

return obj; 

};

下面的代碼給我一個握手錯誤,因爲'connect.sid'屬性與數據庫中的id屬性不匹配。

io.set('authorization', function (data, accept) { 

    if (data.headers.cookie) { 
     data.cookie = utils.parseCookie(data.headers.cookie); 
     data.sessionID = data.cookie['connect.sid']; 
     // **************** // 
     console.log(data.sessionID); 
     // **************** // 
     sessionStore.get(data.sessionID, function (err, session) { 
      if (err || ! session) { 
       accept('Error', false); 
      } else { 
       data.session = session; 
       data.session.url = data.headers.referer; 
       accept(null, true); 
      } 
     }); 
    } else { 
     return accept('No cookie transmitted.', false); 
    } 
}); 

回答

1

看來現在sessionStore鍵較短的UID(24) - 只版本,不再存儲在cookie中的「長」版本。

目前,我通過簡單拆分('。')[0]來檢索uid(24)部分: data.sessionID = cookie ['express.sid']。split('。 「)[0];

+0

雖然這個工作,我認爲它是非常脆弱的,如果他們改變cookie的表示,會打破。我發佈了一個答案,該答案應該不那麼脆弱(即使它使用私有API)。 –

3

我遇到了同樣的問題,而您的解決方案工作時,您使用的parseCookie函數來自舊版本的connect。連接中的新代碼現在會標記Cookie,這是該時間段之後的額外字符。

經過一番在express和connect的內核中搞亂了一番之後,我想出了下面的代碼。儘管它依賴於一些私有的API函數(utils.parseSignedCookies),但它至少使用相同的代碼來解析用於生成cookie的cookie,因此應該對cookie的未來變化不太敏感創建和解析。

/* cookie: the cookie string from the request headers 
* sid: the session 'key' used with express.session() 
* secret: the session 'secret' used with express.session() 
*/ 
function parseSessionCookie(cookie, sid, secret) { 
    var cookies = require('express/node_modules/cookie').parse(cookie) 
    , parsed = require('express/node_modules/connect/lib/utils').parseSignedCookies(cookies, secret) 
    ; 
    return parsed[sid] || null; 
} 

socketIO.set('authorization', function(data, accept) { 
    var sid = parseSessionCookie(data.headers.cookie, 'express.sid', 'secret'); 
    if (sid) { 
    sessionStore.get(sid, function(err, session) { 
     if (err || !session) { 
     accept('Error', false); 
     } else { 
     data.session = session; 
     accept(null, true); 
     } 
    }); 
    } else { 
    return accept('No cookie transmitted.', false); 
    } 
}); 
+0

感謝您的代碼 – starsinmypockets