【问题标题】:Using Passport.SocketIO cookie parser error使用 Passport.SocketIO cookie 解析器错误
【发布时间】:2014-06-11 17:22:52
【问题描述】:

我正在使用以下内容:

"dependencies": {
    "express": "^4.0.0",
    "socket.io": "0.9.16",
    "mongoose": "^3.8.8",
    "passport": "^0.2.0",
    "passport-local": "^1.0.0",
    "express-session": "^1.0.3",
    "cookie-parser": "^1.0.1",
    "body-parser": "^1.0.2",
    "session-mongoose": "git://github.com/danpe/session-mongoose.git#master",
    "passport.socketio": "^3.0.1"
  }

设置我的 socket.io 授权:

io.set("authorization", passportSocketIo.authorize({
    passport : passport,
    cookieParser: cookieParser(),
    key:    settings.sessionKey,  //the cookie where express (or connect) stores its session id.
    secret: settings.sessionSecret,       //the session secret to parse the cookie
    store:  sessionStore,  //the session store that express uses
    fail: function(data, accept) {
        console.log("failed");
        // console.log(data);// *optional* callbacks on success or fail
        accept(null, false);             // second param takes boolean on whether or not to allow handshake
    },
    success: function(data, accept) {
        console.log("success socket.io auth");
        // console.log(data);
        accept(null, true);
    }
}));

当我尝试与我的客户建立联系时:

var socket = io.connect('http://127.0.0.1:3000/');
socket.on('connect', function () {
    // socket connected
    console.log("Socket Connected!");
});

服务器崩溃并出现以下情况:

S:\Server\node_modules\cookie-parser\index.js:27
    var cookies = req.headers.cookie;
                             ^
TypeError: Cannot read property 'cookie' of undefined 
    at Object.cookieParser(S:\Server\node_modules\cookie-parser\index.js:27:30)
    at parseCookie (S:\Server\node_modules\passport.socketio\lib\index.js:4:27)
    at Manager.<anonymous> (S:\Server\node_modules\passport.socketio\lib\index.js:37:19)
    at Manager.authorize (S:\Server\node_modules\socket.io\lib\manager.js:910:31)
    at Manager.handleHandshake (S:\Server\node_modules\socket.io\lib\manager.js:786:8)
    at Manager.handleRequest (S:\Server\node_modules\socket.io\lib\manager.js:593:12)
    at Server.<anonymous> (S:\Server\node_modules\socket.io\lib\manager.js:119:10)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2108:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)

任何想法如何发生?

【问题讨论】:

  • Express 4.x 没有 headers 属性。标头通过 req.get 检索,cookie 在 req.cookies 上。我猜 cookieParser 需要 headers 属性,所以最简单的选择可能是返回到 express 3.x。 expressjs.com/4x/api.html#req.cookies
  • @aembke 我正在使用支持 express 4.x 的最新 CookieParser 代码:if (req.cookies) return next(); 是 cookieParser 中的第一行
  • 嗯,奇怪。那么 req.headers 行从何而来?无论哪个模块试图引用该属性,都需要为 express 4.x 打补丁。可能是passport.socketio?
  • @aembke cookie-parser 第 27 行
  • 有趣,我不确定解决此问题的最简单方法是什么,但您需要该模块不尝试使用 headers 属性的一种或另一种方法。如果 cookie-parser 的维护者相对活跃,可能值得联系他们为 express 4.x 修补他们的代码。否则也许只是自己修补并提交拉取请求?我确定您不是第一个或最后一个想在 express 4.x 中使用 cookie-parser 的人。

标签: node.js authentication express socket.io passport.js


【解决方案1】:

您好,我遇到了同样的问题。

这很合乎逻辑,因为您将一个套接字而不是一个请求传递给 cookie 解析器。只需将 socket.request 传递给 cookie 解析器,它就会被修复。

可以在这里找到解决方案:https://github.com/expressjs/cookie-parser/issues/3#issuecomment-41443866

var cookieParser = require('cookie-parser')(SESSION_SECRET);    

// ### Cookie parser

// Wrapper arround Express cookie parser, so we can use the same cookie parser for socket.io.
// Parse Cookie header and populate `socket.request.cookies` with an object keyed by the cookie names.
// Uses signed cookies by passing a secret string, which assigns `socket.request.secret` so it may be used by other middleware.

function cookieParserWrapper (socket, next) {
  // request, response and callback
  cookieParser(socket.request, {}, next);
}

编辑:

发现了一个有趣的模块socket.io-bundlehttps://github.com/nkzawa/socket.io-bundle/blob/master/lib/cookieParser.js

除了 cookie-parser 包装器外,它还有 express-session 和 csurf 模块的包装器。

【讨论】:

  • 这个包装要做什么?我把它代替了cookieParser: cookieParserWrapper(),,但它给出了同样的错误......
  • 如果您使用上面的代码,只需使用不带括号的io.use(cookieParserWrapper);
【解决方案2】:

这是一个愚蠢的错误,我应该将 cookieParser 作为库而不是实例化对象传递:

var cookieParser= require('cookie-parser');

io.set("authorization", passportSocketIo.authorize({
    passport : passport,
    cookieParser: cookieParser,
    key:    settings.sessionKey,  //the cookie where express (or connect) stores its session id.
    secret: settings.sessionSecret,       //the session secret to parse the cookie
    store:  sessionStore,  //the session store that express uses
    fail: function(data, accept) {
        console.log("failed");
        // console.log(data);// *optional* callbacks on success or fail
        accept(null, false);             // second param takes boolean on whether or not to allow handshake
    },
    success: function(data, accept) {
        console.log("success socket.io auth");
        // console.log(data);
        accept(null, true);
    }
}));

【讨论】:

  • 嗨 Danpe,BTW 集在最新版本的 socket.io 中已弃用。请改用io.use(function (socket, next) { next(); });。 :)
  • 谢谢,但我使用的是 0.9.16,无法移植 1.0.0 以支持 Titanium
猜你喜欢
  • 1970-01-01
  • 2013-11-18
  • 2012-08-26
  • 2015-08-04
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
  • 2017-04-27
相关资源
最近更新 更多