【问题标题】:express-session, connect-redis and einaros/wsexpress-session、connect-redis 和 einaros/ws
【发布时间】:2017-10-28 08:22:37
【问题描述】:

我似乎在让 Express、express-session、connect-redis 和 websockets/ws 很好地配合使用时遇到了一些麻烦。这很可能与我对这些模块和一般编码的理解有限有关。这里的大部分代码取自存储库中的各个示例以及其他试图完成类似任务的来源。

所以我们这里有一个启用 websocket 的应用程序,它试图立即启动到服务器端应用程序的 websocket 连接,它目前只提供 websocket 功能。该请求首先到达我们的 NGINX API 代理,该代理将请求代理到本地运行的 Node 应用程序实例。

Node 应用程序应配置为接受并立即将请求升级到 websocket,创建唯一的会话 id 和 cookie,然后将其存储在我们的 Redis 盒子中。除了 Redis 中的存储之外,所有这些都可以正常工作。

以下代码没有 connect-redis 工作(我直接使用 node_redis 客户端来查询 Redis 框的任何键):

'use strict';

const express = require('express');
const http = require('http');
const ws = require('ws');
const redis = require('redis');
const client = redis.createClient(6379, '10.0.130.10', {no_ready_check: true});
//const RedisStore = require('connect-redis')(session);


var session = require('express-session')({
    //store: new RedisStore({host: '10.0.130.10', port: '6379', ttl: 60, logErrors: true}),
    cookie: {secure: true, maxAge: 3600, httpOnly: true},
    resave: false,
    saveUninitialized: true,
    secret: '12345'
});


// Define Express and WS servers
const app = express();
const server = http.createServer(app);
const wss = new ws.Server({ server });


// Client heartbeat
function heartbeat() {
    this.isAlive = true;
}


// WS Websocket
wss.on('connection', function connection(ws, req) {

    // Obtain Client IP address from NGINX x-forwarded-for proxy header
    let clientIp = req.headers['x-forwarded-for'];

请求后的服务器输出:


监听:10031

会话 ID:eavjOlls59jtjQd-gZ0EIhqf3_P6sYMr

会话 Cookie:{"originalMaxAge":3600,"expires":"2017-05- 27T13:59:19.663Z","secure":true,"httpOnly":true,"path":"/"}

Redis 对索引键的响应:


通过取消注释相关部分来启用connect-redis会在启动时导致服务器上出现以下错误消息:


/home/ubuntu/app/njs/nl-websocket-dev/node_modules/connect-redis/lib/connect-redis.js:39 var Store = session.Store; ^

TypeError:无法读取未定义的属性“存储” 在 module.exports (/home/ubuntu/app/njs/nl-websocket-dev/node_modules/connect-redis/lib/connect-redis.js:39:22) 在对象。 (/home/ubuntu/app/njs/nl-websocket-dev/stackoverflow.js:8:48) 在 Module._compile (module.js:409:26) 在 Object.Module._extensions..js (module.js:416:10) 在 Module.load (module.js:343:32) 在 Function.Module._load (module.js:300:12) 在 Function.Module.runMain (module.js:441:10) 启动时 (node.js:139:18) 在 node.js:968:3


请注意,我以我所做的方式启动了 express-session,因此我可以将其绑定到 websockets/ws。我已经尝试了很多配置,这实际上是唯一允许 express-session 和 websockets/ws 一起工作的配置。我从'Azmisov'这里得到了要点(特别是不包括connect-redis):

ExpressJS & Websocket & session sharing

以这种方式将 express-session 调用到 websockets/ws 中确实起作用。但是,将 connect-redis 添加到 express-session 中,然后在 websockets/ws 中调用该组合是问题开始的地方,使用此配置。

欢迎任何关于如何使这项工作发挥作用的想法。

【问题讨论】:

    标签: node.js express websocket node-redis express-session


    【解决方案1】:

    你在这里使用session

    const RedisStore = require('connect-redis')(session);
    

    稍后将在此处定义:

    var session = require('express-session')(...);
    

    这是第一个问题(session 未定义)。

    另一个问题是 connect-redis 应该传递 require('express-session') 的结果,而您的代码正试图传递它的实例化版本。

    这两个问题都可以这样解决:

    const Session    = require('express-session');
    const RedisStore = require('connect-redis')(Session);
    
    var session = Session({
      store: new RedisStore(...),
      ...
    });
    

    我也看不到 session 在您发布的代码中的任何位置是如何附加到 app 的,但它并不完整,所以我假设您在某个地方调用 app.use(session)

    【讨论】:

    • 首先感谢您对此的帮助,非常感谢。我现在看到我粘贴的代码不完整。试图解决这个问题是我现在发现的这个网站的一个痛苦。我的下一条评论包含对理解我在这里所做的事情似乎很重要的代码。我没有调用 app.use(session) 来获取 websockets 中的会话数据。
    • // WS Websocket wss.on('connection', function connection(ws, req) { session(req, {}, function(){ let sessionId = req.sessionID; console.log('Session ID: ' + sessionId); let sessionCookie = req.session.cookie; console.log('Session Cookie: ' + JSON.stringify(sessionCookie)); }); });
    • 好吧,是的,(session 未定义),这是有道理的,它在被调用时尚未定义。您对我试图通过connect-redis 的实例化版本require('express-session') 的第二个评论是值得细细琢磨的。距离黎明还有四个小时还不够清晰。尝试了您的解决方案,但仍然缺少一些东西,可能是由于我如何将 express-session 调用到 websockets 中。
    • @rhamstra 最后一句话(如何在 websockets 中使用express-session)实际上可能需要一个全新的问题。
    • @robertkep 是的,我知道这是怎么保证的。现在我的直接问题已通过您的更正得到解决,我想我会这样做,以便为可能偶然发现类似问题的每个人留下一些清晰的记录。一直在进一步挖掘。我们的客户立即提出开放握手/升级请求。这似乎绕过了 app.use 的任何实例,因为我在使用它和基本 Express 结构(如 app.get)配置的任何内容上得到零输出。我还不清楚为什么会发生这种情况;-) 感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 2022-01-10
    • 2019-11-04
    相关资源
    最近更新 更多