express.session.MemoryStore не возвращает сессию?

16

Было очень просто настроить сеансы и использовать их в php. Но мой веб-сайт должен иметь дело с веб-сайтами. Я столкнулся с проблемой настройки сеансов в node.js. Я могу легко переносить данные, не используя сеансы, и это будет работать нормально, но когда открыта более одной вкладки, новый сокет будет создан, а ранее открытые вкладки будут работать нормально. Поэтому я работал над сессиями и имел проблемы с доступом к sessionstore, его сеанс регистрации не был схвачен. Я также пробовал с 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 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!');
});
  • 1
    Я думаю, что мы должны следить за socket.id, но я не думаю, что это правильное решение
  • 0
    Не могли бы вы рассказать немного больше о желаемом поведении после открытия новых вкладок? Вы хотите, чтобы они действовали как совершенно новый клиент, или вы хотите, чтобы они использовали один и тот же сеанс?
Показать ещё 3 комментария
Теги:
express
session
socket.io

1 ответ

1

Взгляните на эту статью: авторизация на основе сеанса с помощью 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 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);
    });
});

Затем вы можете иметь страницу клиента под public/client.html в http://localhost:3000/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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню