express-session, connect-redis and einaros/ws

怎甘沉沦 提交于 2019-12-11 07:14:28

问题


I seem to be having some trouble getting Express, express-session, connect-redis and websockets/ws to play together nicely. This most likely has to do with my as yet limited understanding of these modules and coding in general. Most of the code here is taken from the respective examples in the repositories as well as other sources trying to accomplish something similar.

So what we have here is a websocket-enabled app trying to immediately initiate a websocket connection to the server-side app, which does nothing but provide websocket functions currently. This request first hits our NGINX API proxy, which proxies the request to a locally running instance of the Node app.

The Node app should be configured to accept and immediately upgrade the request to websocket, create a unique session id and cookie, which should then be stored inside our Redis box. All of this EXCEPT storage in Redis functions correctly.

The following code WITHOUT connect-redis works (I use the node_redis client directly to query the Redis box for any keys):

'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'];

Server output following a request:


Listening on: 10031

Session ID: eavjOlls59jtjQd-gZ0EIhqf3_P6sYMr

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

Redis reponse for index keys:


Enabling connect-redis by uncommenting the relevant sections leads to the following error message on the server when started:


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

TypeError: Cannot read property 'Store' of undefined at module.exports (/home/ubuntu/app/njs/nl-websocket-dev/node_modules/connect-redis/lib/connect-redis.js:39:22) at Object. (/home/ubuntu/app/njs/nl-websocket-dev/stackoverflow.js:8:48) at Module._compile (module.js:409:26) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) at startup (node.js:139:18) at node.js:968:3


Note that I initiated express-session in the way I did so I could tie it into websockets/ws. I've tried quite a few configurations, and this is literally the only configuration that allowed express-session and websockets/ws to work together. I got the gist from 'Azmisov' here (which notably excludes connect-redis):

ExpressJS & Websocket & session sharing

Calling express-session into websockets/ws in this manner does function. However, adding connect-redis onto express-session and then calling that combination inside websockets/ws is where the problems start, using this configuration.

Any thoughts on how to get this working are most welcome.


回答1:


You're using session here:

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

Which gets defined later on here:

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

So that's the first issue (session being undefined).

The other issue is that connect-redis should be passed the result of require('express-session'), while your code is trying to pass it an instantiated version of it.

Both issues can be solved like this:

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

var session = Session({
  store: new RedisStore(...),
  ...
});

I also don't see how session is being attached to app anywhere in the code you post, but it's not complete so I assume that somewhere you're calling app.use(session).



来源:https://stackoverflow.com/questions/44218539/express-session-connect-redis-and-einaros-ws

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!