Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.IO and Express session not sharing their session

I am trying to connect the sessions of express API and socket.IO server. But it seems both are storing their sessions separately. The socket.IO have the connections session while the express server has the user qid session. I am using express ^4.17.1 and socket.IO ^4.1.2. Here is my code:

/server.js

const express = require("express");
const session = require("express-session");
const sharedSession = require("express-socket.io-session");
const cookieParser = require("cookie-parser");
const app = express();
app.use(cookieParser("secret"));
const corsConfig = {
  origin: function (origin, callback) {
    if (!origin || whitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error("Not allowed by CORS"));
    }
  },
  credentials: true,
};

const server = require("http").createServer(app);
const io = require("socket.io")(server, { cors: corsConfig });

const whitelist = ["http://localhost:3000", "http://192.168.2.104:3000"];

const sessionMiddleware = session({
  secret: "keyboard cat",
  cookie: { maxAge: 60000 },
  name: "qid",
});
// register middleware in Express
app.use(sessionMiddleware);
// register middleware in Socket.IO
io.use((socket, next) => {
  sessionMiddleware(socket.request, {}, next);
  // sessionMiddleware(socket.request, socket.request.res, next); will not work with websocket-only
  // connections, as 'socket.request.res' will be undefined in that case
});

// TRIED, BUT SAME RESULT. . .
// io.use(sharedSession(sessionMiddleware, { autoSave: true }));

app.get("/", (req, res) => {
  req.session.qid = "sdfdsfsadgfas";
  req.session.save();
  console.log(
    "CONNECTIONS / QID (EXPRESS SERVER)",
    req.session.connections,
    req.session.qid
  );
  res.json({ success: true });
});

io.on("connection", (socket) => {
  const session = socket.request.session;
  // console.log(socket.request);
  if (!session.connections) session.connections = 0;
  session.connections++;
  session.save();
  socket.on("a", () => {
    session.reload((err) => {
      if (err) console.log("ERROR", err);

      console.log(
        "CONNECTIONS / QID (IO SERVER)",
        session.connections,
        session.qid
      );
    });
  });
});

const port = process.env.PORT || 5000;
server.listen(port, () => console.log("server listening on port " + port));

/client.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Test</title>
  </head>
  <body></body>
  <script
    src="https://cdn.socket.io/3.1.3/socket.io.min.js"
    integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh"
    crossorigin="anonymous"
  ></script>
  <script>
    const socket = io("http://localhost:5000");
    fetch("http://localhost:5000/").then(() => socket.emit("a"));
  </script>
</html>

Please help me with this. Thanks in advance.

like image 851
plutolaser Avatar asked Oct 17 '25 02:10

plutolaser


1 Answers

You can pass the encrypted session id in the front while connecting, and decrypt it in backend...

Front

const socket = io("http://localhost:5000?session=sessionIdEncrypted");

Backend

io.on("connection", socket => {
    const givenSessionId = socket.handshake.query.session
    // here you decrypt the session id and find it in the store
})
like image 126
BENARD Patrick Avatar answered Oct 18 '25 14:10

BENARD Patrick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!