Expressjs + socket.io + express-session

Tengo este código en mi server.js.

var app = require('express')(), session = require('express-session'), cookie = require('cookie'), cookieParser = require('cookie-parser'), manager = require('./sockets/manager'); var sessionStore = new session.MemoryStore(); app.use(cookieParser('secret')); app.use(session({ name: 'sid', store: sessionStore, secret: 'secret', saveUninitialized: true, resave: true, cookie: { path: '/', httpOnly: true, secure: false, maxAge: null } })); var server = require('http').Server(app).listen(8888), io = require('socket.io')(server); io.use(function(socket, next) { var data= socket.request; if (data.headers.cookie) { data.cookie = cookie.parse(cookieParser.signedCookie(data.headers.cookie, 'secret')); console.log('data.cookies ( %s )', JSON.stringify(data.cookie)); // print 'io=id_place', cookies doesn't have sid, why? if (data.cookie.sid) { data.sid = request.cookie.sid; sessionStore.get(request.cookie.sid, function(err, session) { request.session = session; }); } } next(); }); manager.use(io); 

El registro de la consola me muestra esta cookie request.cookies ({“io”: “lHKSseNH5UrnJisSAAAA”}). Acabo de ver muchos ejemplos con Expressjs 3 y socket 0.9, pero tengo:

“socket.io”: “^ 1.0.6”, “express”: “~ 4.5.1”, “express-session”: “~ 1.6.4”

y no funciona.

¿Tengo algún error?

He creado una solución para ti: introduce la descripción del enlace aquí . Como puede ver, el objeto socket tiene una propiedad de intercambio que incluye encabezados de solicitud con cookie.

El siguiente enlace tiene una solución muy simple para compartir sesión entre Express y Socket.IO.

Respuesta simple

La API de middleware de Express 4.x está tan cerca de Socket.IO 1.x que podemos usar el mismo middleware de sesión para ambos.

El ejemplo de allí utiliza la tienda de sesión MongoDB. Probé con el almacén de sesión predeterminado de la sesión rápida y funcionó.

io.js

 var io = require('socket.io')(); io.on('connection', function (socket) { console.log(socket.request.session); console.log('New client connected!'); }); module.exports = io; 

app.js

 var express = require('express'), path = require('path'), favicon = require('serve-favicon'), logger = require('morgan'), cookieParser = require('cookie-parser'), bodyParser = require('body-parser'), expressSession = require('express-session'), io = require('./io'), index = require('./routes/index'), app = express(), mongoose = require('mongoose'), uri = 'localhost:27017/selfie_showcase', options = { db: { native_parser: true }, server: { socketOptions: { keepAlive: 1 } }, replset: { socketOptions: { keepAlive: 1 } }, user: 'arun', pass: 'arun' }, sessionMiddleware = expressSession({ secret: 'my_s3cr3t_s3ss1on', resave: true, saveUninitialized: true }); // connect to MongoDB mongoose.connect(uri, options, function(err) { if(err) { console.log(err); } }); // configure socket.io to share session with express io.use(function(socket, next) { sessionMiddleware(socket.request, {}, next); }); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(sessionMiddleware); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { title: 'Error', message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { title: 'Error', message: err.message, error: {} }); }); module.exports = app; 

bin / www

 #!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var io = require('../io'); var debug = require('debug')('selfie-showcase:server'); var http = require('http'); /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * Create HTTP server. */ var server = http.createServer(app); io.attach(server); /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } 

Espero que esto pueda ayudar a los futuros usuarios.

PD: utilicé Express-generador así que este tipo de módulo se dividió.

Prueba este módulo express-socket.io-session .

Le permite compartir datos de sesión basados ​​en cookies entre Express y socket.io (y viceversa).

Puede usar el almacenamiento que desee para los datos de la sesión porque crea el objeto de sesión rápida de forma regular y luego lo comparte con socket.io.

Funciona para Express> 4.0 y socket.io> 1.0