Saturday, 27 May 2017

express-session, connect-redis and einaros/ws

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.



via rhamstra

No comments:

Post a Comment