我正在尝试在使用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软件包时,软件包中有一个示例目录.针对此模块的工作示例进行测试可能会派上用场.