question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Upgraded to 4.x and objects in socket.request.session no longer exists

See original GitHub issue

Describe the bug socket.request.session is always a new session even after declaring req.session.user with a value.

To Reproduce

Setup Socket.io with express-session middleware.

Socket.IO server version: ^4.1.1

Server

import { Server, Socket } from 'socket.io';
import session from 'express-session';

const io = new Server(http.createServer(/* express app */), { /* cors /* });

const wrapper = (middleware: any) => (socket: Socket, next: any) => middleware(socket.request, {}, next);

io.use(wrapper(session(/* session configs */)));

io.on('connection', (socket: Socket) => {
  const req = socket.request

  console.log(req.session) // Typescript will warn that session is not in IncomingMessage
  
  // console.log output shows no user
  /* Session {
    cookie: {
      path: '/',
      _expires: 2021-05-18T13:06:36.146Z,
      originalMaxAge: 3600000,
      httpOnly: true,
      domain: undefined
    }
  } */
});

app.use((req, resp, next) => {
  console.log(req.session) // user is in session
  req.io = io;

  next();
});

app.post('/login', (req, resp, next) => {
  const user =  // login user

  req.session.user = user
});

// server listen and stuff

Socket.IO client version: ^4.1.1

Client

import { io } from "socket.io-client";

const socket = io("http://localhost", {});

socket.on("connect", () => {
  console.log(`connect ${socket.id}`);
});

socket.on("disconnect", () => {
  console.log("disconnect");
});

Expected behavior socket.request.session should have user property in it when initializing session in express middleware (eg. - req.session.user = user)

Platform:

  • Device: Desktop and Mobile
  • OS: Windows 10 and Android 10

Additional context

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:4
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
microspec-chriscommented, Aug 5, 2021

I’m having the similar issue with the following versions: express 4.17.1 express-session 1.17.2 socket.io 3.1.2

0reactions
Rc85commented, Jun 14, 2022

I’ve decided to try upgrading to 4.x today from 2.x and running into issues with properties in req.session from showing up. The session object is in request now, so that is good news. My set up is a little different as I have 4 session middlewares (eg. admin, merchant, customer, and courier) and depending on what endpoint the user is sending a request from, I have to authenticate that user using the specified session middleware.

With that set up, I also have to use the session middleware depending on which namespace the client is connecting from. For example, if they are connecting from io('/merchant') then I have to do .io.of('/merchant').use on my server.

I’ve followed the guide you posted, but the issue I am running into is setting up the server options using the example posted above here. I try just using one of my session middleware with your example but I am still not getting user in req.session. Here are some of my code.

// The 4 session middleware setup I have
app.use(/^\/api\/v2\/(account|restaurants)\/.*/, customerSessionMiddleware);
app.use(/^\/api\/v2\/merchant\/.*/, merchantSessionMiddleware);
app.use(/^\/api\/v2\/admin\/.*/, adminSessionMiddleware);
app.use(/^\/api\/v2\/courier\/.*/, courierSessionMiddleware);

const io = new Server(server, {
  pingTimeout: 30000,
  cors: {
    origin: 'http://localhost:3000',
    credentials: true
  },
  allowRequest: (req, callback) => {
    const fakeRes = {
      getHeader() {
        return [];
      },
      setHeader(key: string, values: string[]) {
        req.cookieHolder = values[0];
      },
      writeHead() {}
    };
    // trying with just the merchant session middleware
    merchantSessionMiddleware(req as Request, fakeRes as unknown as Response, () => {
      if (req.session) {
        // trigger the setHeader() above
        fakeRes.writeHead();
        // manually save the session (normally triggered by res.end())
        req.session.save();
      }
      callback(null, true);
    });
  }
});

io.engine.on('initial_headers', (headers: { [key: string]: string }, req: IncomingMessage) => {
  if (req.cookieHolder) {
    headers['set-cookie'] = req.cookieHolder;

    delete req.cookieHolder;
  }
});

merchantSocket(io)

And then in merchantSocket.

export const merchantSocket = (io: Server) => {
  io.of('/merchant').use((socket, next) =>
    merchantSessionMiddleware(socket.request as Request, {} as Response, next as NextFunction)
  );

  io.of('/merchant').on('connection', (socket: Socket) => {
    const req = socket.request;

    socket.on('join_location', (data) => {
      req.session.reload(async (err: any) => {
        if (err) console.log(err);
        req.session.save();

        console.log(req.session);
      });
    });
  });
}

I log into my app, emit the join_location event and this is what I get in console.log, no user.

Session {
  cookie: {
    path: '/',
    _expires: 2022-06-14T22:29:36.375Z,
    originalMaxAge: 3600000,
    httpOnly: true
  }
}

#4383 got it working. So what am I doing wrong? And with a 4 session middleware setup, how do I configure the server options for 4 middlewares?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to share sessions with Socket.IO 1.x and Express 4.x?
The solution is surprisingly simple. It's just not very well documented. It is possible to use the express session middleware as a Socket....
Read more >
Advanced Usage — Requests 2.28.1 documentation
This document covers some of Requests more advanced features. Session Objects¶. The Session object allows you to persist certain parameters across requests. It ......
Read more >
Private messaging - Part II - Socket.IO
Exchanging private messages is currently based on the socket.id attribute, ... IO session and will change every time the low-level connection between the ......
Read more >
Migrating to Express 4
Express 4 no longer depends on Connect, and removes all built-in middleware from its core, except for the express.static function. This means that...
Read more >
Fix list for IBM WebSphere Application Server V8.5
noSuchMethodException. PH38010, Update the migration toolkit for application binaries to the latest version - 21.0.0.2. Object Request Broker (ORB) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found