Nodejs socketio 使用过io.set('authorization',function(){.....}) 后得不到session 具体看图片
Nodejs socketio 使用过io.set(‘authorization’,function(){…}) 后得不到session 具体看图片
console.log(session)显示为undefined 请问这是怎么回事
根据你描述的问题,当使用 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 函数有问题了
})
解决了 谢谢 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.IO 的 io.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');
});
解释:
- Express Session 配置:使用
express-session
和RedisStore
来存储会话数据。 - 授权函数:在授权函数中,通过查询参数(假设存在)获取会话 ID,并从会话存储中获取对应的会话对象。
- 会话存储:需要找到 Express 中间件栈中的
session
层,并从中获取会话存储对象。 - 会话传递:将获取到的会话对象附加到
handshakeData
中,这样在 Socket 连接建立时就可以访问到会话信息。
确保在客户端发送 WebSocket 连接请求时,包含正确的会话 ID 查询参数(例如 ?sid=your-session-id
)。这样服务器端的授权函数才能正确获取到会话信息。