Session Node JS expess会话在docker上运行时未定义,但在MAC上运行良好

Session Node JS expess会话在docker上运行时未定义,但在MAC上运行良好,session,express,docker,redis,Session,Express,Docker,Redis,我有一个简单的节点JS web应用服务器,允许用户登录和发布/编辑一个简单的博客。我使用Redis作为会话存储,使用CouchDB作为数据库。我在MAC上运行一切(节点应用程序、Redis、沙发数据库),并使用MAC上运行的浏览器连接到它(或本地主机:3001)。我可以登录、发布/编辑博客,一切正常 上周,我尝试对接我的NodeJS应用程序。基本上,我的节点应用程序在docker容器上运行,但是我的redis和couchdb继续在主机(即我的MAC)上运行。我已经使用docker机器对节点应用程

我有一个简单的节点JS web应用服务器,允许用户登录和发布/编辑一个简单的博客。我使用Redis作为会话存储,使用CouchDB作为数据库。我在MAC上运行一切(节点应用程序、Redis、沙发数据库),并使用MAC上运行的浏览器连接到它(或本地主机:3001)。我可以登录、发布/编辑博客,一切正常

上周,我尝试对接我的NodeJS应用程序。基本上,我的节点应用程序在docker容器上运行,但是我的redis和couchdb继续在主机(即我的MAC)上运行。我已经使用docker机器对节点应用程序进行了docker化

Docker机器(Docker VM)具有IP:192.168.99.101
我的MAC IP:192.168.0.100

我以(192.168.99.101:3001连接浏览器&我看到了登录页面。然后输入日志凭证。我的浏览器将页面发布到docker上的节点应用程序。节点应用程序从CouchDB(在MAC主机上运行)读取用户passwd,并成功验证密码是否正确。但是,节点服务器无法从POST请求对象获取有效会话,因此无法保存会话。我在网上浏览了很多关于这个主题的stackoverflow和其他文章,但没有一篇是有用的

我已经确定网络不是问题。也就是说,我可以使用curl命令从DockerShell访问redis&couchdb

将浏览器连接到其他物理IP是否导致此问题?我应该换域名吗?我想更好地了解这里发生了什么。谢谢你的帮助

初始化:

登录函数在docker上运行时未看到Cookie或会话。在我的MAC电脑上运行时,它可以看到一切。

在docker上运行时,我看到以下错误:

/usr/src/app/mysource.js:760
           postReq.session.key = userName;
                               ^

TypeError: Cannot set property 'key' of undefined
    at IncomingMessage.<anonymous> (/usr/src/app/mysource.js:760:26)
    at emitNone (events.js:72:20)
    at IncomingMessage.emit (events.js:166:7)
    at endReadableNT (_stream_readable.js:913:12)
    at nextTickCallbackWith2Args (node.js:442:9)
    at process._tickCallback (node.js:356:17)
/usr/src/app/mysource.js:760
postReq.session.key=用户名;
^
TypeError:无法设置未定义的属性“key”
在收到消息时。(/usr/src/app/mysource.js:760:26)
在emitNone(events.js:72:20)
在IncomingMessage.emit(events.js:166:7)
在endReadableNT(_stream_readable.js:913:12)
在下一个TTickCallbackwith2args(node.js:442:9)
在进程中调用(node.js:356:17)
我已尽我所能验证了以下内容:
1) 节点应用程序在我的MAC上运行良好
2) docker和MAC之间没有网络问题。我可以从docker shell访问redis、couchDB
3) package.json和节点模块在MAC和docker环境中是相同的
4) 阅读了几篇关于这一主题的文章,但看不出哪里出了问题


请帮忙

最后,我用我的代码解决了这个问题。非常感谢Rudemanuel提供了关于为redisClient添加事件侦听器的非常有用的提示

当我添加事件监听器时,我的节点应用程序的docker部署不断抛出与redis的连接错误,如下所示:

UNABLE to establish connection with Redis
{ [Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379]
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 6379 }
回想一下,我已经初始化了express会话,如下所示,所以我不明白为什么它会继续连接到localhost,尽管我指定了正确的redis主机

const redisClient  = redis.createClient();
:
:
app.use(
   session(
   {
    secret: REDIS_SECRET_KEY,
    // create new redis store.
    store: new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl :  260}),
    // REDIS_SERVER_HOST = 192.168.0.100, REDIS_SERVER_PORT=6379
    saveUninitialized: false,
    resave: false,
    cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 }
   }));
下面的陈述似乎就是问题所在:

new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl :  260})
当我初始化redisClient时,客户端默认为localhost和6379,随后当我使用客户端和主机端口信息初始化redisStore时,redisStore对象将忽略主机/端口并获取客户端对象的参数。为了解决这个问题,我做了以下工作:

redisClient  = redis.createClient(REDIS_SERVER_PORT, REDIS_SERVER_HOST);
:
:

 app.use(session(
       {
        secret: REDIS_SECRET_KEY,
        // create new redis store.
        store: new redisStore({client: redisClient, ttl:  260}),
        saveUninitialized: false,
        resave: false,
        cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 }
       }));

这就解决了问题。非常非常感谢这个论坛,我能够很快解决我的问题。你们太棒了

最后,我用我的代码解决了这个问题。非常感谢Rudemanuel提供了关于为redisClient添加事件侦听器的非常有用的提示

当我添加事件监听器时,我的节点应用程序的docker部署不断抛出与redis的连接错误,如下所示:

UNABLE to establish connection with Redis
{ [Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379]
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 6379 }
回想一下,我已经初始化了express会话,如下所示,所以我不明白为什么它会继续连接到localhost,尽管我指定了正确的redis主机

const redisClient  = redis.createClient();
:
:
app.use(
   session(
   {
    secret: REDIS_SECRET_KEY,
    // create new redis store.
    store: new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl :  260}),
    // REDIS_SERVER_HOST = 192.168.0.100, REDIS_SERVER_PORT=6379
    saveUninitialized: false,
    resave: false,
    cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 }
   }));
下面的陈述似乎就是问题所在:

new redisStore({ host: REDIS_SERVER_HOST, port: REDIS_SERVER_PORT, client: redisClient,ttl :  260})
当我初始化redisClient时,客户端默认为localhost和6379,随后当我使用客户端和主机端口信息初始化redisStore时,redisStore对象将忽略主机/端口并获取客户端对象的参数。为了解决这个问题,我做了以下工作:

redisClient  = redis.createClient(REDIS_SERVER_PORT, REDIS_SERVER_HOST);
:
:

 app.use(session(
       {
        secret: REDIS_SECRET_KEY,
        // create new redis store.
        store: new redisStore({client: redisClient, ttl:  260}),
        saveUninitialized: false,
        resave: false,
        cookie: { expires: false, maxAge: 30 * 24 * 60 * 60 * 1000 }
       }));

这就解决了问题。非常非常感谢这个论坛,我能够很快解决我的问题。你们太棒了

尝试将事件侦听器添加到redis客户端,以帮助您调试连接。下面是我刚才放在一起的一个示例,它应该可以用于您的设置。请尝试向redis客户端添加事件侦听器,以帮助您调试连接。这里有一个例子,我刚才放在一起,应该与您的设置。