繁体   English   中英

快速会话不会设置cookie connect.sid

[英]express-session won't set cookie connect.sid

编辑5

我的后端和前端在192.168.80.213/backend后端地址可访问的LAMP环境中运行。 我尝试使用nodejs,socket.io和express框架来链接后端和前端来制作推送通知服务器。

我的nodejs服务器正在监听端口3000而我的后端和前端都正在使用Apache监听端口80。

这是我的节点客户端:

<script type="text/javascript" src="socket.io-1.4.5.js"></script>
<script type="text/javascript">
    var socket = io('http://192.168.80.213:3000/');
</script>

这是我的节点服务器:

const   express          = require('express')
        , app            = express()
        , http           = require('http').Server(app)
        , socketIo       = require('socket.io')(http)
        , cookieParser   = require('cookie-parser')
        , cookie         = require('cookie')
        , connect        = require('connect')
        , expressSession = require('express-session')
        , port           = 3000
        , helmet         = require('helmet')
        , name           = 'connect.sid'
        , sessionStore   = new expressSession.MemoryStore({ reapInterval: 60000 * 10 })
        , sessionSecret  = 'VH6cJa7yZSmkRbmjZW#J3%CDn%dt'
        , environment    = process.env.NODE_ENV || 'development'
        ;

/** Configuration **/
app.enable('trust proxy');
app.disable('x-powered-by');
app.use(helmet());
app.use(cookieParser());
app.use(expressSession({
    'name'  : name,
    'secret': sessionSecret,
    'store' : sessionStore,
    'resave': true,
    'saveUninitialized': true
}));

app.get('/', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello from node');
});

socketIo.use(function(socket, callback) {
    // Read cookies from handshake headers
    var cookies = cookie.parse(socket.handshake.headers.cookie);
    // We're now able to retrieve session ID
    var sessionID;
    if (cookies[name]) {
        console.log( "cookies['" + name + "'] = " + cookies[name] );
        sessionID = cookieParser.signedCookie( cookies[name], sessionSecret );
        console.log( "sessionID = " + sessionID );
    }else{
        console.log( "cookies['" + name + "'] = undefined" );
    }

    if (!sessionID) {
        console.log('ERROR NO SESSION CONNECTION REFUSED !!');
        callback('No session', false);
    } else {
        // Store session ID in handshake data, we'll use it later to associate
        // session with open sockets
        socket.handshake.sessionID = sessionID;
        callback(null, true);
    }

});


socketIo.on('connection', function (socket) { // New client
    console.log( 'new connection..' );
    console.log('user ' + socket.handshake.sessionID + ' authenticated and is now connected.');  

});

/** Start server */
http.listen(port);
console.log( "listening on :" + port );

转到192.168.80.213:3000并查看“来自节点的Hello”,并根据以下屏幕截图设置cookie ['connect.sid']

正确设置connect.sid cookie

和控制台输出:

在此处输入图片说明

现在清除缓存,然后我将转到我的后端应用程序,其中的nodeClient 192.168.80.213/backend在哪里。

connect.sid cookie不存在

在此处输入图片说明

和控制台输出:

在此处输入图片说明

为什么快速会话没有设置cookie.sid? 我该如何解决? 我是Node和表达的新手,我花了很多次没有成功的谷歌搜索,希望一些Node Master可以帮助我!

问候

我不知道您使用的是哪个版本的socket.io,但是在版本1.0( > 1.0 )之后:

  • 要注册中间件,您应该使用socketIo.use (请参阅文档
  • 第一个参数是传入套接字 ,可以通过socket.request访问请求
  • 默认情况下,快速会话会使用connect.sid名称保存cookie,如果要使用io名称,则应明确设置它(请参阅name选项
  • 当您想解析签名的cookie时,应提供sessionSecret而不是sessionStore
  • 最后,我认为握手支持已被弃用,您应该将所需的任何内容直接附加到套接字 (请参阅authentication-differences )。

考虑到上述因素,您可以使用以下中间件来Authenticate套接字:

// every incoming socket should pass this middleware
socketIo.use(function(socket, next) {
  var cookies = cookie.parse(socket.request.headers.cookie);
  var sessionID = cookieParser.signedCookie(cookies['connect.sid'], sessionSecret);
  sessionStore.get(sessionID, function(err, session) {
    if ( session && session.isAuthenticated ) {
      socket.userId = session.user.id;
      return next();
    } else {
      return next(new Error('Not Authenticated'));
    }
  });
});
// when connected ...
socketIo.on('connection', function(socket) {
  console.log('user ' + socket.userId + ' authenticated and is now connected.')
});

在这里,我认为你设置isAuthenticated布尔值和user会话,当用户登录。

还请记住,内置在sessionStore中的MemoryStore不适合生产环境:

默认的服务器端会话存储MemoryStore不是专门为生产环境设计的。 在大多数情况下,它将泄漏内存,不会扩展到单个进程,而是用于调试和开发。

因此,您必须考虑使用其他会话存储,例如:

我没有使用cookie或cookie解析器的经验,并且通常对节点不熟悉,但是如果有帮助的话,我有一个类似的系统可以通过访问服务器端会话变量来验证套接字连接。

将会话详细信息保存在变量中

var sessionStorage = expressSession({
'secret': sessionSecret,
'store' : sessionStore,
'resave': true,
'saveUninitialized': true 
});

让socketIo和应用程序使用存储

socketIo.use(function (socket, next) {
    sessionStorage(socket.request, socket.request.res, next);
});
app.use(sessionStorage);

然后在连接内部,您可以使用以下命令访问这些会话变量:

socket.request.res.session.[variable name]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM