我正在尝试在使用websocket时为我的用户实施授权步骤.
当用户连接时,令牌将作为查询值传递给服务器.在服务器级别,我在数据库中查询与传递的令牌匹配的会话.如果找到会话,我会做其他一些检查以确保令牌未被劫持.
问题
会话数据似乎在每次重新加载页面时都被清除.或者服务器无法将sessionId链接到创建它的用户,因此每次生成新会话时都是如此.
我很困惑如何访问会话变量“如果它们被设置.”
我的代码问题
当用户重新加载他/她的页面/客户端时,会话数据将在新请求中变为未定义.会话很好,直到页面刷新,这是我的问题.即使用户刷新页面,我也需要能够保持会话处于活动状态.
问题
如何确保在每次刷新页面时都不清除会话数据?
这是我的授权码
io.set('authorization',function (handshakeData,accept) { var session = handshakeData.session || {}; //This is always undefined! console.log('Session Data:' + session.icwsSessionId); //var cookies = handshakeData.headers.cookie; var token = handshakeData._query.tokenId || ''; //console.log('Token: ' + token); if(!token){ console.log('Log: token was not found'); return accept('Token was found.',false); } //allow any user that is authorized if(session && session.autherized && token == session.token){ console.log('Log: you are good to go'); return accept('You are good to go',true); } //if the client changed their token "client logged out" //terminate the open session before opening a new one if (session.autherized && token != session.token){ var icwsConnection = new icwsConn(icwsRequest); icwsRequest.setConnection(session.icwsServer,session.icwsPort); icwsRequest.setIcwsHeaders(session.icwsSessionId,session.icwsToken); icwsConnection.logout(); session.autherized = false; session.token = null; session.icwsServer = null; session.icwsPort = null; session.icwsSessionId = null; session.icwsToken = null; icwsConnection = null; }
如果需要,这是我的整个代码
var env = require('./modules/config'),app = require('express')(),https = require('https'),fs = require('fs'),session = require('express-session'),redisStore = require("connect-redis")(session),sharedsession = require("express-socket.io-session"),base64url = require('base64url'); const server = https.createServer( { key: fs.readFileSync('certs/key.pem'),cert: fs.readFileSync('certs/cert.pem') },function (req,res){ res.setHeader('Access-Control-Allow-Origin','*'); res.setHeader('Access-Control-Allow-Headers','X-Requested-With,Content-Type'); } ).listen(env.socket.port,env.socket.host,function () { console.log('\033[2J'); console.log('Websocket is running at https://%s:%s',server.address().address,server.address().port); }); var io = require('socket.io')(server); const sessionMiddleware = session({ store: new redisStore({ host: env.redis.host,port: env.redis.port }),secret: env.session.secret,name: env.session.name,rolling: false,resave: true,saveUninitialized: true }); app.use(sessionMiddleware); // Use shared session middleware for socket.io // setting autoSave:true io.use(sharedsession(sessionMiddleware,{ autoSave: true })); var icwsReq = require('./modules/icws/request.js'),icwsConn = require('./modules/icws/connection.js'),icwsInter = require('./modules/icws/interactions.js'),sessionValidator = require('./modules/validator.js'); var clients = {}; var icwsRequest = new icwsReq(); var sessionChecker = new sessionValidator(); app.get('/',res) { res.send('welcome'); }); io.set('authorization',true); } /* if (!originIsAllowed(origin)) { // Make sure we only accept requests from an allowed origin socket.destroy(); console.log((new Date()) + ' Connection from origin ' + origin + ' rejected.'); return false; } */ //if the client changed their token "client logged out" //terminate the open session before opening a new one if (session.autherized && token != session.token){ var icwsConnection = new icwsConn(icwsRequest); icwsRequest.setConnection(session.icwsServer,session.icwsToken); icwsConnection.logout(); session.autherized = false; session.token = null; session.icwsServer = null; session.icwsPort = null; session.icwsSessionId = null; session.icwsToken = null; icwsConnection = null; } var myIP = '10.0.4.195'; var decodedToken = base64url.decode(token); sessionChecker.validateData(decodedToken,myIP,env.session.duration,function(isValid,icws){ if(isValid){ session.authorized = true; session.icwsServer = icws.host; session.icwsPort = icws.port; session.token = token; session.icwsSessionId = null; session.icwsToken = null; icwsRequest.setConnection(icws.host,icws.port); var icwsConnection = new icwsConn(icwsRequest); icwsConnection.login(icws.username,icws.password,function(isLogged,icwsSession,headers){ if(isLogged && icwsSession.sessionId && icwsSession.csrfToken){ //icwsConnection.setWorkstation(icws.workstaton); session.icwsSessionId = icwsSession.sessionId; session.icwsToken = icwsSession.csrfToken; icwsRequest.setIcwsHeaders(session.icwsSessionId,session.icwsToken); console.log('Log: new connection to ICWS! ' + session.icwsSessionId ); } }); console.log('Log: new connection to websocket!') return accept('New connection to websocket!',true); } else { console.log('Log: token could not be validated!'); return accept('Token could not be validated!',false); } }); }); io.on('connection',function (socket) { console.log('Authorized Session! Websocket id ready for action!'); //var origin = socket.request.headers.origin || ''; //var myIP = socket.request.socket.remoteAddress || ''; if(!socket.request.sessionID){ console.log('Missing Session ID'); return false; } var socketId = socket.id; var sessionID = socket.request.sessionID; //Add this socket to the user's connection if(userCons.indexOf(socketId) == -1){ userCons.push(socketId); } clients[sessionID] = userCons; console.log(clients); //display all connected clients socket.on('placeCall',function(msg){ icwsInter.call(method,uri,params,header,true); }); socket.on('chat',function(msg){ console.log('Chat Message: ' + msg); socket.emit('chat',{ message: msg }); }); socket.on('disconnect',function(msg){ console.log('Closing sessionID: ' + sessionID); var userCons = clients[sessionID] || []; var index = userCons.indexOf(socketId); if(index > -1){ userCons.splice(index,1); console.log('Removed Disconnect Message: ' + msg); } else { console.log('Disconnect Message: ' + msg); } }); socket.on('error',function(msg){ console.log('Error Message: ' + msg); }); }); function originIsAllowed(origin) { // put logic here to detect whether the specified origin is allowed. var allowed = env.session.allowedOrigins || [] if(allowed.indexOf(origin) >= 0){ return true; } return false; }
编辑
每个请求都会更改io cookie.创建io cookie时,它的最后访问值为12/31/1969 4:00:00 PM
此外,此cookie在每次重新加载页面时都会更改.
在下面的@Osk建议之后这是我的新代码,它仍然没有在页面重新加载时保存我的会话数据.
var env = require('./modules/config'),base64url = require('base64url'),cookieParser = require("cookie-parser"); const server = https.createServer( { key: fs.readFileSync('certs/key.pem'),server.address().port); }); var io = require('socket.io')(server); var sessionStore = new redisStore({ host: env.redis.host,port: env.redis.port }); const sessionMiddleware = session({ store: sessionStore,rolling: true,resave: false,saveUninitialized: false,cookie: { maxAge: 60 * 60 * 1000 } }); app.use(sessionMiddleware); // Use shared session middleware for socket.io // setting autoSave:true io.use(sharedsession(sessionMiddleware,{ autoSave: false })); var icwsReq = require('./modules/icws/request.js'),sessionValidator = require('./modules/validator.js'); var clients = {}; var icwsRequest = new icwsReq(); var sessionChecker = new sessionValidator(); app.get('/',res) { res.send('welcome'); }); //Middleware for authorizing a user before establishing a connection io.use(function(socket,next) { var origin = socket.request.headers.origin || ''; if (!originIsAllowed(origin)) { // Make sure we only accept requests from an allowed origin socket.destroy(); console.log((new Date()) + ' Connection from origin ' + origin + ' rejected.'); return false; } var myIP = socket.request.socket.remoteAddress || ''; var token = socket.handshake.query.tokenId || ''; var session = socket.handshake.session || {}; //This should be defined on a reload console.log('IP Address: ' + myIP + ' SessionID: ' + socket.handshake.sessionID); if(!token){ console.log('Log: token was not found'); return next(new Error('Token not found')); } //allow any user that is authorized if(session && session.autherized && token == session.token){ console.log('Log: you are good to go'); return next(new Error('You are good to go')); } //if the client changed their token "client logged out" //terminate the open session before opening a new one if (session.autherized && token != session.token){ var icwsConnection = new icwsConn(icwsRequest); icwsRequest.setConnection(session.icwsServer,session.icwsToken); icwsConnection.logout(); session.autherized = false; session.token = null; session.icwsServer = null; session.icwsPort = null; session.icwsSessionId = null; session.icwsToken = null; icwsConnection = null; session.save(); } var decodedToken = base64url.decode(token); sessionChecker.validateData(decodedToken,icws.port); var icwsConnection = new icwsConn(icwsRequest); /* icwsConnection.login(icws.username,session.icwsToken); console.log('Log: new connection to ICWS! ' + session.icwsSessionId ); } }); */ session.save(function(){ console.log('Log: new connection to websocket!'); }); return next(); } else { console.log('Log: token could not be validated!'); return next(new Error('Token could not be validated!')); } }); }); io.on('connection',function (socket) { console.log('Connection is validated and ready for action!'); var socketId = socket.id; if(!socket.handshake.sessionID){ console.log('sessionId was not found'); return false; } var sessionID = socket.handshake.sessionID; var userCons = clients[sessionID] || []; //Add this socket to the user's connection if(userCons.indexOf(socketId) == -1){ userCons.push(socketId); } clients[sessionID] = userCons; //console.log(clients); socket.on('placeCall',function(msg){ icws.call(method,function(msg){ console.log('Error Message: ' + msg); }); }); function originIsAllowed(origin) { // put logic here to detect whether the specified origin is allowed. var allowed = env.session.allowedOrigins || [] if(allowed.indexOf(origin) >= 0){ return true; } return false; }
解决方法
express-socket.io-session与socket.io 1.x一起使用
我看到你正在调用在socket.io 1.x上弃用的io.set()
有关此问题的更多信息,请查看标识身份验证差异下的http://socket.io/docs/migrating-from-0-9/.
在那里,它说明了
The old
io.set()
andio.get()
methods are deprecated and only
supported for backwards compatibility.”
这可能与您的问题有关吗?
安装express-socket.io-session软件包时,软件包中有一个示例目录.针对此模块的工作示例进行测试可能会派上用场.