Socket.io can't access same session as Express

2019-07-27 07:25发布

问题:

I'm trying to use express and socket.io with shared sessions, I got it already once working, but somehow it won't work anymore.

I followed this link How to share sessions with Socket.IO 1.x and Express 4.x? and got access to session on socket.io, but it's not somehow same session. It seems that every socket.io connection it generates new session.

Express

req.session.test == 'Some value'

Socket.io

socket.request.session.test == undefined

Am I missing something, or is it a bug with some of those modules?

-- Edit -- Edit -- Edit --

Found what causes the problem is that i when I set cookie with following

cookie: {
    domain: '.local.fi' 
}

I need to have same session across subdomains, how can I do it if not this way as many pages succested?

-- Edit -- Edit -- Edit --

package.json

{
   "dependencies": {
      "express": "^4.13.4",
      "express-session": "^1.13.0",
      "socket.io-session": "^0.0.5",
      "express-socket.io-session": "^1.3.1",    
       "socket.io": "^1.4.5"
   }
}

Start of my index.js

'use strict'
var express = require('express'),
    session = require('express-session'),
    app = express(),
    server = require('http').Server(app),
    io = require('socket.io')(server)

I create sessionMiddleware like this

let connection = mongoose.createConnection('mongodb://localhost/sessions')
var sessionMiddleware = session({
    secret: 'session-secret',
    saveUninitialized: true,
    resave: true,
    name: 'sess.sid',
    store: new MongoStore({
        mongooseConnection: connection,
        ttl: 60 * 60 * 172800
    }),
    cookie: {
        domain: '.local.fi',
        maxAge: 1000 * 60 * 60 * 172800
    }
})

And attach it like this

app.use(sessionMiddleware)
io.use(function(socket, next) {
    sessionMiddleware(socket.request, socket.request.res, next)    
})

Express routes

app.get('/', function(req, res) {
    if(!req.session.test)
        req.session.test = 'Some value'
    res.send(`
        <html>
            <head>
                <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
                <script type='text/javascript' src='/socket.io/socket.io.js'></script>
                <script>
                    $(document).ready(function() {
                        var sio = io.connect('localhost')
                        sio.on('connected', function(data) {
                            $('#list').empty()
                            console.log(data)
                        })
                        sio.on('broadcast', function(data) {
                            $('#list').append($(data))
                        })
                    })
                </script>
            </head>
            <body>
                <h5> Session result => ${req.session.test} </h5>
                <div>
                    <ul id='list'></ul>
                </div>
            </body>
        </html>

    `)
})

Socket.io routes

io.on('connection', function(socket) {
    console.log('Client connected')
    socket.emit('connected', { response: 'connection', session: socket.request.session})
    var tick = 0
    var interval = setInterval(function() {
        tick++
        socket.emit('broadcast', `<li>Tick ${socket.request.session.test}</li>`)
        if(tick>100)
            clearInterval(interval)
    }, 1000)
})

And end of index.js

server.listen(80)
console.log('Test listening port 80')

I tried also with these but without any help

socket.io-session https://www.npmjs.com/package/socket.io-session

express-socket.io-session https://www.npmjs.com/package/express-socket.io-session

回答1:

✓ Found resolution for this issue.

Problem was when I connect socket.io on client side.

I set cookie domain as .local.fi and connected to localhost

On declaration

cookie: {
    domain: '.local.fi'
}

Clientside

From

var socket = io.connect('localhost')

To

var socket = io.connect('local.fi')


回答2:

I would change

session = session({... 

to

sessionMiddleware = session({...

You are overwriting the session variable that you declare earlier in

session = require('express-session')

so you are most likely running into conflicts by doing that. So you would have

var sessionMiddleware = session({
  secret: 'session-secret',
  saveUninitialized: true,
  resave: true,
  name: 'sess.sid',
  store: new MongoStore({
    mongooseConnection: connection,
    ttl: 60 * 60 * 172800
  }),
  cookie: {
    domain: '.local.fi',
    maxAge: 1000 * 60 * 60 * 172800/*,
    expires: moment().add(7, 'days')*/
  }
})
app.use(sessionMiddleware)
io.use(function(socket, next) {
  sessionMiddleware(socket.request, socket.request.res, next)    
})