Nodejs 在express + socket.io + session 中如何在socket.io里面获取session 求赐教

Nodejs 在express + socket.io + session 中如何在socket.io里面获取session 求赐教

11 回复

Nodejs 在express + socket.io + session 中如何在socket.io里面获取session 求赐教

在使用 ExpressSocket.ioSession 的项目中,经常需要在 WebSocket 连接中访问用户会话信息。这通常涉及到将 Express 的会话信息传递给 Socket.io。以下是如何实现这一功能的步骤。

环境准备

首先,确保你已经安装了必要的依赖包:

npm install express socket.io express-session

示例代码

  1. 初始化 Express 和 Socket.io

    const express = require('express');
    const http = require('http');
    const socketIo = require('socket.io');
    const session = require('express-session');
    
    const app = express();
    const server = http.createServer(app);
    const io = socketIo(server);
    
    // 配置 session
    app.use(session({
      secret: 'your_secret_key',
      resave: false,
      saveUninitialized: true,
      cookie: { secure: false } // 如果使用 HTTPS, 设置为 true
    }));
    
  2. 设置一个简单的路由来测试 session

    app.get('/', (req, res) => {
      req.session.username = 'exampleUser';
      res.send('Session set, now open a WebSocket connection.');
    });
    
  3. Socket.io 中获取 session

    在这里,我们需要创建一个中间件来获取当前用户的 session 并将其传递给 WebSocket 连接。

    const RedisStore = require('connect-redis')(session);
    
    // 使用 Redis 存储 session (可选)
    app.use(session({
      store: new RedisStore(),
      secret: 'your_secret_key',
      resave: false,
      saveUninitialized: true,
      cookie: { secure: false }
    }));
    
    // 创建一个中间件来获取 session
    function getSessionFromSocket(socket, next) {
      const sessionId = socket.handshake.query.sessionId;
      if (!sessionId) return next(new Error('No session ID provided'));
    
      // 假设你使用 Redis 存储 session
      req.sessionStore.get(sessionId, (err, session) => {
        if (err || !session) return next(err || new Error('Session not found'));
        socket.request.session = session;
        next();
      });
    }
    
    // 将中间件应用到所有连接
    io.use(getSessionFromSocket);
    
    // 监听连接事件
    io.on('connection', (socket) => {
      console.log('A user connected with session:', socket.request.session.username);
      socket.on('disconnect', () => {
        console.log('User disconnected');
      });
    });
    
    server.listen(3000, () => {
      console.log('Server listening on port 3000');
    });
    
  4. 客户端发送 session ID

    在客户端,你需要在 WebSocket 连接时传递 session ID:

    let socket = io({
      query: { sessionId: 'your_session_id_here' }
    });
    

通过以上步骤,你可以在 Socket.io 连接中访问 Express 的会话信息。注意,这里的 sessionId 需要在客户端请求时从服务器获取并传递过来。


  1. server.js
//session & cookie
var sessionStore = new express.session.MemoryStore({reapInterval: 60000 * 10});
app.use(express.cookieParser());
app.use(express.session({
  store: sessionStore,
  key: 'sid',
  secret: config['session_secret']
}));

//start http server && socket.io var server = http.createServer(app); var io = require(‘socket.io’).listen(server,{ ‘log level’: 2, ‘browser client minification’: true }); var chatServer = require(’./controllers/chat’).init(io, app, sessionStore);

2. chat.js

/**
 * 初始化ChatServer
 */
exports.init = function(io, app, sessionStore){
  var chatServer = io.of('/chat');
  var userList = {};

chatServer.authorization(function (handshakeData, callback) { //没有cookie则退出 if (!handshakeData.headers.cookie) return callback(‘socket.io: no found cookie.’, false);

  //根据cookie找sessionId,https://github.com/DanielBaulig/sioe-demo/blob/master/app.js
  var signedCookies = require('express/node_modules/cookie').parse(handshakeData.headers.cookie);
  handshakeData.cookies = require('express/node_modules/connect/lib/utils').parseSignedCookies(signedCookies,
  app.get('config')['session_secret']);

  //根据sessionId找username
  sessionStore.get(handshakeData.cookies['sid'], function(err,session){
    if(err || !session) return callback('socket.io: no found session.', false);
    handshakeData.session = session;
    if(handshakeData.session.user){ 
      return callback(null, true);
    }else{
      return callback('socket.io: no found session.user', false);
    }
  })

});

呵呵,我也同样的问题,几乎同样的代码,求大神。表示写rails的自学node.js很有压力

额,2了,原来有回复。。。把大神当提问人了额。。。

这个适用express3.0

2.0也能用

赞! 不过有个细节不太一样

var signedCookies = express_cookie.parse(handshakeData.headers.cookie);

handshakeData.cookies = parseCookie(signedCookies[‘connect.sid’],settings[‘cookie_secret’]);

sessionStore.get(handshakeData.cookies, function(err,session){

cookie parse出来是个对象,所以要变成signedCookies[‘connect.sid’],handshakeData.cookies并且不会直接有sid这个key

p.s 引用路径换掉了,清楚些

使用session.socket.io这个模块.

要在使用 Express、Socket.IO 和 Session 的 Node.js 应用中从 Socket.IO 中获取 Session,可以使用 express-socket.io-session 这个中间件。这个中间件可以帮助你在 Socket.IO 连接中轻松访问到 Express 的 Session。

步骤

  1. 安装必要的库

    npm install express socket.io express-session cookie-parser express-socket.io-session
    
  2. 配置 Express 和 Socket.IO

const express = require('express');
const http = require('http');
const session = require('express-session');
const socketIo = require('socket.io');
const cookieParser = require('cookie-parser');
const sessionIo = require('express-socket.io-session');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 配置 session
app.use(cookieParser());
app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: false } // 如果你使用的是 HTTPS,则设置为 true
}));

// 使用 express-socket.io-session 中间件
io.use(sessionIo(session({
    autoSave: true
})));

io.on('connection', (socket) => {
    console.log('A user connected');
    
    // 访问 session
    const sessionData = socket.handshake.session;
    
    console.log('Session data:', sessionData);

    socket.on('disconnect', () => {
        console.log('User disconnected');
    });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  • express-session: 用于处理会话。
  • cookie-parser: 用于解析客户端的 cookie。
  • express-socket.io-session: 这个中间件允许你在 Socket.IO 的连接上下文中访问到 Express 的会话。

通过上述代码,当一个客户端连接到服务器时,你可以通过 socket.handshake.session 来访问到当前用户的会话信息。这样你就可以在 Socket.IO 的事件处理器中使用这些会话数据了。

回到顶部