Nodejs socketio 使用过io.set('authorization',function(){.....}) 后得不到session 具体看图片

Nodejs socketio 使用过io.set(‘authorization’,function(){…}) 后得不到session 具体看图片

这是模块

这是session

这里设置socketio的authorization

这里是调用

console.log(session)显示为undefined 请问这是怎么回事


6 回复

根据你描述的问题,当使用 io.set('authorization', function (handshakedata, accept) {...}) 方法来设置 Socket.IO 的认证逻辑时,可能会导致无法获取到 session。这是因为默认情况下,Socket.IO 并不会自动将 Express 的 session 传递给 WebSocket 连接。

解释

在传统的 HTTP 请求中,Express 可以通过中间件(如 express-session)轻松管理 session。然而,在 WebSocket 连接中,这种机制需要额外配置,因为 WebSocket 连接是一个持久连接,不涉及传统的 HTTP 请求头。

示例代码

假设你已经有一个基于 Express 和 Socket.IO 的应用,并且想要在 WebSocket 连接时验证用户 session。你可以这样做:

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
}));

// 设置 authorization
io.set('authorization', function (handshakedata, accept) {
    // 从请求中获取 cookie
    const cookies = handshakedata.headers.cookie;
    
    // 解析 cookie
    let parsedCookies = {};
    if (cookies) {
        cookies.split(';').forEach(function(cookie) {
            let parts = cookie.match(/(.*?)=(.*)$/);
            parsedCookies[parts[1].trim()] = (parts[2] || '').trim();
        });
    }
    
    // 从 session store 中查找 session
    app._session(parsedCookies['connect.sid'], function(err, sess) {
        if (err || !sess) {
            return accept('Session not found', false);
        }

        // 将 session 信息附加到 handshake data
        handshakedata.session = sess;

        // 接受连接
        return accept(null, true);
    });
});

// 监听连接事件
io.on('connection', function(socket) {
    console.log('A user connected:', socket.handshake.session);
});

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

注意事项

  • 确保你已经在 Express 应用中正确配置了 express-session
  • io.set('authorization', ...) 函数中,你需要解析客户端发送的 cookie,并从 session store 中检索 session 对象。
  • 将 session 信息存储在 handshakedata 中,以便在后续的 WebSocket 通信中可以访问它。

这样配置后,你应该能够成功获取到 session 信息。


io.set("authorization",function(hsd,cb){
           console.log(hsd.headers.cookie)//输出有数据那就是  parseCookie 函数有问题了
})

参考 http://cnodejs.org/topic/50efdc29df9e9fcc580eb134

解决了 谢谢 I got it

在问您个问题 为什么我的nodejs+socketio+jade+mongodb程序在本地用ie8可以打开 上传到服务器上ie8就打不开了 能帮我看看嘛 谢谢 地址

用 Chrome 可以 QQ浏览器就不行了 会卡在 ‘‘正在连接服务器’…’ 对应停在socketio的

socket.on('connect',function(){
        showtip('welcome    '+username)
        $('#connectstart').fadeOut();
        $('#msg').removeAttr('disabled')
        $('#room').fadeIn(1000)
    })

根据你的描述和提供的图片,你遇到的问题是因为在使用 Socket.IOio.set('authorization', function (handshakeData, callback) { ... }) 方法时,没有正确地从请求中提取会话信息。你需要确保在验证过程中能够访问到有效的会话对象。

以下是一个示例代码,展示如何正确地获取和使用会话信息:

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);

// 初始化 Express 应用
const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 配置 Session
app.use(session({
    store: new RedisStore({/* Redis 配置 */}),
    secret: 'your-secret',
    resave: false,
    saveUninitialized: false,
}));

// 自定义授权函数
io.set('authorization', function (handshakeData, accept) {
    const sessionId = handshakeData.query.sid; // 假设查询参数中有会话ID

    // 从 Session 存储中获取当前会话
    const sessionStore = app._router.stack.find(layer => layer.name === 'session')?.handle?.store;
    if (!sessionStore) {
        return accept('Session store not found', false);
    }

    sessionStore.get(sessionId, (err, session) => {
        if (err || !session) {
            return accept('Session not found', false);
        }

        // 将会话信息添加到 handshakeData
        handshakeData.session = session;

        // 接受连接
        return accept(null, true);
    });
});

// 处理 Socket 连接
io.on('connection', (socket) => {
    console.log(socket.handshake.session); // 输出会话信息
});

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

解释:

  1. Express Session 配置:使用 express-sessionRedisStore 来存储会话数据。
  2. 授权函数:在授权函数中,通过查询参数(假设存在)获取会话 ID,并从会话存储中获取对应的会话对象。
  3. 会话存储:需要找到 Express 中间件栈中的 session 层,并从中获取会话存储对象。
  4. 会话传递:将获取到的会话对象附加到 handshakeData 中,这样在 Socket 连接建立时就可以访问到会话信息。

确保在客户端发送 WebSocket 连接请求时,包含正确的会话 ID 查询参数(例如 ?sid=your-session-id)。这样服务器端的授权函数才能正确获取到会话信息。

回到顶部