express.session.MemoryStore 不返回会话?

Posted

技术标签:

【中文标题】express.session.MemoryStore 不返回会话?【英文标题】:express.session.MemoryStore not returning session? 【发布时间】:2013-08-20 13:37:22 【问题描述】:

设置会话并在 php 中使用它们真的很容易。但是我的网站需要处理 WebSockets。我在 node.js 中设置会话时遇到问题。我可以在不使用会话的情况下轻松推送数据,它可以正常工作,但是当打开多个选项卡时,会创建新的 socket.id 并且之前打开的选项卡将无法正常工作。所以我一直在处理会话并且在访问会话存储时遇到问题,它的日志会话没有被抓取。我也尝试过 session.load 但没有运气

如何获取会话对象并以打开其他选项卡不会影响功能并在所有选项卡上将数​​据从服务器推送到客户端的方式使用它?

var express=require('express');
var http = require('http');
var io = require('socket.io');
var cookie = require("cookie");
var connect = require("connect"),
MemoryStore = express.session.MemoryStore,
sessionStore = new MemoryStore();

var app = express();

app.configure(function () 
    app.use(express.cookieParser());
    app.use(express.session(store: sessionStore
        , secret: 'secret'
        , key: 'express.sid'));
    app.use(function (req, res) 
        res.end('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
    );
);

server = http.createServer(app);
server.listen(3000);

sio = io.listen(server);

var Session = require('connect').middleware.session.Session;

sio.set('authorization', function (data, accept) 
    // check if there's a cookie header
    if (data.headers.cookie) 
        // if there is, parse the cookie
        data.cookie = connect.utils.parseSignedCookies(cookie.parse(data.headers.cookie),'secret');
        // note that you will need to use the same key to grad the
        // session id, as you specified in the Express setup.
        data.sessionID = data.cookie['express.sid'];
        sessionStore.get(data.sessionID, function (err, session) 
            if (err || !session) 
                // if we cannot grab a session, turn down the connection
                console.log("session not grabbed");
                accept('Error', false);
             else 
                // save the session data and accept the connection
                console.log("session grabbed");
                data.session = session;
                accept(null, true);
            
        );
     else 
       // if there isn't, turn down the connection with a message
       // and leave the function.
       return accept('No cookie transmitted.', false);
    
    // accept the incoming connection
    accept(null, true);
);

sio.sockets.on('connection', function (socket) 
    console.log('A socket with sessionID ' + socket.handshake.sessionID 
        + ' connected!');
);

【问题讨论】:

我想我们必须跟踪 socket.id 但我认为这不是正确的解决方案 你能多说一下打开新标签后你想要的行为吗?您希望他们表现得像一个全新的客户,还是希望他们共享同一个会话? err 有什么吗?还是!session 告诉你没有会话? sessionerrundefined。但sessionStore 拥有所有用户会话数据 我发现了类似的问题[***.com/questions/8863644/…你试过了吗? [1]:***.com/questions/8863644/… 【参考方案1】:

看看这篇文章:Session-based Authorization with Socket.IO

您的代码运行良好,但需要 2 处改进才能完成您想要的工作(从服务器向客户端发送会话数据):

    它仅在授权期间提取sessionID 它在连接期间通过此sessionID 从存储中提取会话数据,您可以在此间隔内将数据从服务器发送到客户端。

这是改进后的代码:

var express = require('express');
var connect = require('connect');
var cookie = require('cookie');
var sessionStore = new express.session.MemoryStore();    

var app = express();    

app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session(store: sessionStore, secret: "secret", key: 'express.sid'));
// web page
app.use(express.static('public'));    

app.get('/', function(req, res) 
  var body = '';
  if (req.session.views) 
    ++req.session.views;
   else 
    req.session.views = 1;
    body += '<p>First time visiting? view this page in several browsers :)</p>';
  
  res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
);    

var sio = require('socket.io').listen(app.listen(3000));   

sio.set('authorization', function (data, accept) 
    // check if there's a cookie header
    if (data.headers.cookie) 
        // if there is, parse the cookie
        var rawCookies = cookie.parse(data.headers.cookie);
        data.sessionID = connect.utils.parseSignedCookie(rawCookies['express.sid'],'secret');    
        // it checks if the session id is unsigned successfully
        if (data.sessionID == rawCookies['express.sid']) 
            accept('cookie is invalid', false);
        
     else 
       // if there isn't, turn down the connection with a message
       // and leave the function.
       return accept('No cookie transmitted.', false);
    
    // accept the incoming connection
    accept(null, true);
);    

sio.sockets.on('connection', function (socket) 
    //console.log(socket);
    console.log('A socket with sessionID ' + socket.handshake.sessionID + ' connected!');
    // it sets data every 5 seconds
    var handle = setInterval(function() 
        sessionStore.get(socket.handshake.sessionID, function (err, data) 
            if (err || !data) 
                console.log('no session data yet');
             else 
                socket.emit('views', data);
            
        );
    , 5000);    

    socket.on('disconnect', function() 
        clearInterval(handle);
    );
);

然后,您可以在http://localhost:3000/client.htmlpublic/client.html 下拥有一个客户端页面,以查看从http://localhost:3000 填充的会话数据:

<html>
<head>
    <script src="/socket.io/socket.io.js" type="text/javascript"></script>
    <script type="text/javascript">
        tick = io.connect('http://localhost:3000/');
        tick.on('data', function (data) 
            console.log(data);
        );

        tick.on('views', function (data) 
            document.getElementById('views').innerText = data.views;
        );

        tick.on('error', function (reason)
          console.error('Unable to connect Socket.IO', reason);
        );

        tick.on('connect', function ()
          console.info('successfully established a working and authorized connection');
        );
    </script>
</head>
<body>
    Open the browser console to see tick-tocks!
    <p>This session is viewed <b><span id="views"></span></b> times.</p>
</body>

【讨论】:

以上是关于express.session.MemoryStore 不返回会话?的主要内容,如果未能解决你的问题,请参考以下文章