我使用Socket.io设置了一个websocket,并在node.js服务器上表达了4个框架.

我正在尝试在使用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;
}

解决方法

你使用的是哪个版本的socket.io?

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() and io.get() methods are deprecated and only
supported for backwards compatibility.”

这可能与您的问题有关吗?

安装express-socket.io-session软件包时,软件包中有一个示例目录.针对此模块的工作示例进行测试可能会派上用场.

javascript – 如何在Socket.io/express-sessions中访问/保存授权事件的会话数据?的更多相关文章

  1. html5 http的轮询和Websocket原理

    这篇文章主要介绍了html5 http的轮询和Websocket原理的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. HTML5 3D书本翻页动画的实现示例

    这是一款十分炫酷的HTML5 3D书本翻页动画,效果相对比较简单,拖拽鼠标模拟用手翻页,需要的朋友们下面随着小编来一起学习学习吧

  4. 使用postMessage让 iframe自适应高度的方法示例

    这篇文章主要介绍了使用postMessage让 iframe自适应高度的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. iOS Swift上弃用后Twitter.sharedInstance().session()?. userName的替代方案

    解决方法如果您仍在寻找解决方案,请参阅以下内容:

  6. 使用Fabric SDK iOS访问Twitter用户时间线

    我试图在这个问题上挣扎两天.我正在使用FabricSDK和Rest工具包,试图为Twitter使用不同的RestAPIWeb服务.我可以使用具有authTokenSecret,authToken和其他值的会话对象的TWTRLogInButton成功登录.当我尝试获取用户时间线时,我总是得到失败的响应,作为:{“errors”:[{“code”:215,“message”:“BadAuthentic

  7. ios – UIPopoverController出现在错误的位置

    所以我花了一些时间寻找答案,但到目前为止还没有找到任何答案.我正在尝试从UIInputAccessoryView上的按钮呈现弹出窗口.UIBarButtonItem我想显示popover来自定制视图,所以我可以使用图像.我创建这样的按钮:当需要显示popover时,我这样做:但我得到的是:弹出窗口看起来很好,但它应该出现在第一个按钮上时出现在第二个按钮上.然后我发现了这个问题:UIBarButto

  8. ios – 如何从Apple Watch调用iPhone上定义的方法

    有没有办法从Watchkit扩展中调用iPhone上的类中定义的方法?根据我的理解,目前在Watchkit和iPhone之间进行本地通信的方法之一是使用NSUserDefaults,但还有其他方法吗?

  9. 如何使用iOS SDK保存LinkedIn访问令牌?

    我在我的iOS应用程序中使用LinkedIn.我想保存访问令牌以供将来使用.令牌属于非属性类型,无法直接保存在NSUserDefaults中.我尝试使用NSKeyedArchiver,但我得到了输出:令牌中的文本即将到来,但值将为空.代码段1:我也尝试像这样保存,但结果是一样的:代码段2:我的编码或访问令牌有什么问题需要一些特殊技术来保存吗?请建议.解决方法这就是我拯救的方式.它对我有用.希望它有所帮助以这种方式使用保存的responseBody我希望这次我很清楚

  10. ios – 如何将视频从AVAssetExportSession保存到相机胶卷?

    在此先感谢您的帮助.解决方法只需使用session.outputURL=…

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部