简体   繁体   English

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

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

EDIT 5 编辑5

I have back and front end running on LAMP environment accesible with 192.168.80.213/backend adress. 我的后端和前端在192.168.80.213/backend后端地址可访问的LAMP环境中运行。 I try to make a push notification server using nodejs, socket.io and express framework to link back and front end. 我尝试使用nodejs,socket.io和express框架来链接后端和前端来制作推送通知服务器。

My nodejs server is listening on port 3000 while my backend and front end listenning on port 80 both using apache. 我的nodejs服务器正在监听端口3000而我的后端和前端都正在使用Apache监听端口80。

Here is my node client : 这是我的节点客户端:

<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>

Here is my node server : 这是我的节点服务器:

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

Go to 192.168.80.213:3000 and see 'Hello from node' and cookie['connect.sid'] is set according to screenshot below 转到192.168.80.213:3000并查看“来自节点的Hello”,并根据以下屏幕截图设置cookie ['connect.sid']

正确设置connect.sid cookie

And console output : 和控制台输出:

在此处输入图片说明

Now Clearing cache and i'm going to my back end app where is my nodeClient 192.168.80.213/backend . 现在清除缓存,然后我将转到我的后端应用程序,其中的nodeClient 192.168.80.213/backend在哪里。

connect.sid cookie doesn't exist connect.sid cookie不存在

在此处输入图片说明

And console output : 和控制台输出:

在此处输入图片说明

Why express-session ain't set cookie.sid ? 为什么快速会话没有设置cookie.sid? how can i fix that ? 我该如何解决? I'm new to node and express, i spend many times googling without succes, hope some node masters coul help me !! 我是Node和表达的新手,我花了很多次没有成功的谷歌搜索,希望一些Node Master可以帮助我!

regards 问候

I dont know which version of socket.io you are using but after version 1.0 ( > 1.0 ): 我不知道您使用的是哪个版本的socket.io,但是在版本1.0( > 1.0 )之后:

  • To register a middleware you should use socketIo.use (See documentation ) 要注册中间件,您应该使用socketIo.use (请参阅文档
  • First parameter is incoming socket which have access to request through socket.request 第一个参数是传入套接字 ,可以通过socket.request访问请求
  • express session by default save cookies with connect.sid name if you want to use io name you should set it explicitely (See name option ) 默认情况下,快速会话会使用connect.sid名称保存cookie,如果要使用io名称,则应明确设置它(请参阅name选项
  • When you want to parse a signed cookie you should provide it sessionSecret not sessionStore 当您想解析签名的cookie时,应提供sessionSecret而不是sessionStore
  • and finally i think handshake support is deprecated and you should attach anything you want directly to socket (See authentication-differences ). 最后,我认为握手支持已被弃用,您应该将所需的任何内容直接附加到套接字 (请参阅authentication-differences )。

With considering aboves you could use a middleware like following to Authenticate your sockets: 考虑到上述因素,您可以使用以下中间件来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.')
});

Here i consider you set isAuthenticated Boolean value and user on session when users logged in. 在这里,我认为你设置isAuthenticated布尔值和user会话,当用户登录。

Also bear in mind that built in sessionStore , MemoryStore is not suit for production environment: 还请记住,内置在sessionStore中的MemoryStore不适合生产环境:

The default server-side session storage, MemoryStore, is purposely not designed for a production environment. 默认的服务器端会话存储MemoryStore不是专门为生产环境设计的。 It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. 在大多数情况下,它将泄漏内存,不会扩展到单个进程,而是用于调试和开发。

So you must consider using another session store like: 因此,您必须考虑使用其他会话存储,例如:

I don't have experience using cookie or cookie-parser and am generally new to node, but I had a similar system to authenticate socket connections by accessing server side session variables if that helps at all. 我没有使用cookie或cookie解析器的经验,并且通常对节点不熟悉,但是如果有帮助的话,我有一个类似的系统可以通过访问服务器端会话变量来验证套接字连接。

Save the session details inside a variable 将会话详细信息保存在变量中

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

let socketIo and app use the storage 让socketIo和应用程序使用存储

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

and then inside on connect you can access those session variables using: 然后在连接内部,您可以使用以下命令访问这些会话变量:

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

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

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