3

socket.ioがセッションを検索すると、CookieのIDがデータベースのIDと一致しないため、ハンドシェイクエラーが発生します。Express3、mongodb、connect-mongodb、socket.iov0.9.10を使用しています

たとえば、含まれているsocket.ioコードからのconsole.log(data.sessionID)の結果は、次のように出力されます。

s:eFFkUnQXWdTO7GBRDc11No/a.U6voj5QnxKs1skq766nO7/qJvPEJA73KaQM67qNEs/k

しかし、データベースのセッションコレクションを見ると、次の_idが表示されます。

"_id" : "eFFkUnQXWdTO7GBRDc11No/a",

ご覧のとおり、これはs:の後およびピリオドの前のdata.sessionIDに対応します。2つの異なるCookieパーサーを使用してみました。以下のパーサーのコードは、express3に含まれているcookieモジュールからのものです。すべてのcookieIDがこのパターンに従っているかどうかわからないため、結果を自分で再度解析する必要があるのか​​、それとも私が何かあるのかわかりません。間違ったこと。

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

2 に答える 2

3

同じ問題が発生しました。ソリューションは機能していますが、使用しているparseCookie関数は古いバージョンのconnectのものです。connectの新しいコードは、ピリオドの後の余分な文字であるCookieに署名するようになりました。

ExpressとConnectの根性をいじくり回した後、次のコードを思いつきました。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);
  }
}); 
于 2012-12-12T15:16:31.337 に答える
1

sessionStoreキーは、uid(24)のみの短いバージョンになり、Cookieに保存されている「長い」バージョンではなくなったようです。

今のところ、単純なsplit('。')[0]を実行してuid(24)部分を取得することで修正しました:data.sessionID = cookie ['express.sid']。split('。')[0] ;

于 2012-09-01T08:01:25.200 に答える