2013-09-23 18 views
3

我在解析express/connect應用程序中的簽名cookie時遇到問題。連接簽名的cookie解析falsy

io.set('authorization', function (handshakeData, callback) { 
    if(handshakeData.headers.cookie) { 
     var signedCookies = cookie.parse(decodeURIComponent(handshakeData.headers.cookie)); 
     handshakeData.cookie = connect.utils.parseSignedCookies(signedCookies, secret); 
    } else { 
     return accept('No cookie transmitted', false); 
    } 
    callback(null, true); // error first callback style 
}); 

發生什麼情況是調用connect.utils.parseSignedCookies返回空對象。我查看了解析函數的源代碼,發現它調用了unsign方法,該方法獲取編碼值的子字符串,然後嘗試用相同的祕密再次對其進行簽名,並比較結果以驗證其編碼的值相同,出於某種原因失敗並且值不匹配。我不知道我做錯了什麼,爲什麼這些值不同,爲什麼我無法獲得正確的會話ID。

我的應用程序初始化代碼如下所示:

app.use(express.cookieParser(secret)); 
app.use(express.session({ 
    key: 'sessionID', 
    secret: secret, 
    maxAge: new Date(Date.now() + 3600000), 
    store: new RedisStore({ 
     client: redisClient 
    }) 
})); 

請幫助,並指出我在做什麼錯在這裏。謝謝

回答

2

cookie解析器是一箇中間件,所以我們必須像使用它一樣。它實際上會填充您傳遞給它的對象。這是你將要如何使用的解析器:

// we need to use the same secret for Socket.IO and Express 
var parseCookie = express.cookieParser(secret); 

io.set('authorization', function(handshake, callback) { 
    if (handshake.headers.cookie) { 
    // pass a req, res, and next as if it were middleware 
    parseCookie(handshake, null, function(err) { 
     // use handshake.signedCookies, since the 
     // cookie parser has populated it 
    }); 
    } else { 
    return accept('No session.', false); 
    } 
    callback(null, true); 
}); 

該Cookie解析器API改變,這是它看起來像現在:

module.exports = function cookieParser(secret) { 
    return function cookieParser(req, res, next) { 
    if (req.cookies) return next(); 
    var cookies = req.headers.cookie; 

    req.secret = secret; 
    req.cookies = {}; 
    req.signedCookies = {}; 

    if (cookies) { 
     try { 
     req.cookies = cookie.parse(cookies); 
     if (secret) { 
      req.signedCookies = utils.parseSignedCookies(req.cookies, secret); 
      req.signedCookies = utils.parseJSONCookies(req.signedCookies); 
     } 
     req.cookies = utils.parseJSONCookies(req.cookies); 
     } catch (err) { 
     err.status = 400; 
     return next(err); 
     } 
    } 
    next(); 
    }; 
}; 

所以我們正在做的是通過handshake作爲什麼一個請求對象,解析器將讀取headers.cookie屬性。然後,cookies將被解析,並放入req.signedCookies。由於我們通過handshake作爲req,因此Cookie現在位於handshake.signedCookies。請注意,因爲您將secret傳遞給解析器,所以Cookie僅進行了簽名。

+0

謝謝您的回答,這種方式更有意義,做到這一點,但遺憾的是它不工作,要麼出於某些原因。下面是已簽名和重新簽名的值的截圖 - 它仍然不同:http://grab.by/qyra我真的不知道該怎麼辦... –

+0

你是如何在你的代碼中使用cookie解析器的? – hexacyanide

+0

代碼與您的解析部分幾乎相同。但我不確定是否將它作爲中間件正確添加。它在會話中間件之前和路由器中間件之前。當我回家後,我會嘗試發佈整個代碼,也許會有任何想法.. –

0

我用cookies/sessions/socket.io等左右問題。最終@vytautas評論幫了我。如果有人看到這一點,請確保您連接到正確的主機,無論您是將它設置爲本地主機還是IP地址或您有什麼。否則,您將無法解析傳入的Cookie。

(事後看來似乎有點明顯。)