ExpressJS & Websocket & session sharing
I found this works for me. Not sure it's the best way to do this though. First, initialize your express application:
// whatever your express app is using here...var session = require("express-session");var sessionParser = session({ store: session_store, cookie: {secure: true, maxAge: null, httpOnly: true}});app.use(sessionParser);
Now, explicitly call the session middleware from the WS connection. If you're using the express-session
module, the middleware will parse the cookies by itself. Otherwise, you might need to send it through your cookie-parsing middleware first.
If you're using the websocket
module:
ws.on("request", function(req){ sessionParser(req.httpRequest, {}, function(){ console.log(req.httpRequest.session); // do stuff with the session here });});
If you're using the ws
module:
ws.on("connection", function(req){ sessionParser(req.upgradeReq, {}, function(){ console.log(req.upgradeReq.session); // do stuff with the session here });});
For your convenience, here is a fully working example, using express
, express-session
, and ws
:
var app = require('express')();var server = require("http").createServer(app);var sessionParser = require('express-session')({ secret:"secret", resave: true, saveUninitialized: true});app.use(sessionParser);app.get("*", function(req, res, next) { req.session.working = "yes!"; res.send("<script>var ws = new WebSocket('ws://localhost:3000');</script>");});var ws = new require("ws").Server({server: server});ws.on("connection", function connection(req) { sessionParser(req.upgradeReq, {}, function(){ console.log("New websocket connection:"); var sess = req.upgradeReq.session; console.log("working = " + sess.working); });});server.listen(3000);
I was able to get this working. I think you need to specify the secret on cookieParser instead of session store.
Example from my app:
var app = express();var RedisStore = require('connect-redis')(express);var sessionStore = new RedisStore();var cookieParser = express.cookieParser('some secret');app.use(cookieParser);app.use(express.session({store: sessionStore}));wss.on('connection', function(rawSocket) { cookieParser(rawSocket.upgradeReq, null, function(err) { var sessionID = rawSocket.upgradeReq.signedCookies['connect.sid']; sessionStore.get(sessionID, function(err, sess) { console.log(sess); }); });});
In version 3.2.0 of ws
you have to do it a bit differently.
There is a full working example of express session parsing in the ws
repo, specifically using a new feature verifyClient
.
A very brief usage summary:
const sessionParser = session({ saveUninitialized: false, secret: '$eCuRiTy', resave: false})const server = http.createServer(app)const wss = new WebSocket.Server({ verifyClient: (info, done) => { console.log('Parsing session from request...') sessionParser(info.req, {}, () => { console.log('Session is parsed!') done(info.req.session.userId) }) }, server})wss.on('connection', (ws, req) => { ws.on('message', (message) => { console.log(`WS message ${message} from user ${req.session.userId}`) })})