how to access authenticated user details in socket.io with express.js and passport.js?

Viewed 46

My goal is to access the authenticated user details, who are connected with the socket server. I am using passport.js for authentication. and using google strategy. and using express-session for managing sessions. I used socket middleware to merge passport.js and socket.io sessions. by doing this I can get the session id when any user establishes a connection with the socket server. but the problem is when I am trying to access user details I am getting user is undefined. But I am getting user details through the rest APIs in the HTTP request from the browser.

this is my index.js file where I am listening my express.js and socket.io server

const express = require("express");
const http = require("http");
const mongoose = require("mongoose");
var morgan = require("morgan");
const passport = require("passport");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const cors = require("cors");

require("dotenv").config();
require("./Auth/PassportSetup");

// App instance
const app = express();

//Database Connection
mongoose
  .connect(process.env.DATABASE)
  .then(console.log("Database is connected with server "))
  .catch((error) => {
    console.log(error);
  });

// Cors
app.use(cors({ origin: "http://localhost:3000", credentials: true }));

// Ws session
const sessionMiddleware = session({
  secret: "cats",
  resave: true,
  saveUninitialized: true,
  cookie: { secure: false, maxAge: 1000 * 60 * 60 * 24 * 365 },
  store: MongoStore.create({
    mongoUrl: process.env.DATABASE,
   
  }),
});
// Working with session
app.use(sessionMiddleware);

// Passport initialization
app.use(passport.initialize());
app.use(passport.session());

// Routes
const AuthRoute = require("./Routes/AuthRoute");

// using routes
app.use(AuthRoute);

// Using middlewares
app.use(morgan("tiny"));

app.get("/", (req, res) => {
  res.send("Hello World!");
});

const server = http.createServer(app);
// SocketServer.CreateSocketConnection(server, sessionMiddleware);
const io = require("socket.io")(server, {
  cors: { origin: "http://localhost:3000 " },
});

const wrap = (middleware) => (socket, next) =>
  middleware(socket.request, {}, next);

io.use(wrap(sessionMiddleware));
io.use(wrap(passport.initialize()));
io.use(wrap(passport.session()));

io.on("connection", (socket) => {
  // I can access session from here
  const session = socket.request.session;
  console.log(socket.request.session);
  console.log(`saving sid ${socket.id} in session ${session.id}`);

  // and the session looks like
  //   Session {
  //   cookie: {
  //     path: '/',
  //     _expires: 2023-09-14T03:35:29.458Z,
  //     originalMaxAge: 31536000000,
  //     httpOnly: true,
  //     secure: false
  //   }
  // }

  //But I want user deatils when i am trying to access user details its returning undefined because in the session object there is no user property.
  //    var userId = socket.request.session.passport.user;
});

server.listen(process.env.PORT, () => {
  console.log(`Server listening on port ${process.env.PORT} ⚙️`);
});

this is my passportSetup.js file where i am managing passport.js

const GoogleStrategy = require("passport-google-oauth20").Strategy;
const FacebookStrategy = require("passport-facebook").Strategy;
const GitHubStrategy = require("passport-github2").Strategy;
const passport = require("passport");
const User = require("../Models/User");

// Using google strategy
passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: `${process.env.BACKEND_BASE_URL}/auth/google/callback`,
    },
    async function (accessToken, refreshToken, profile, done) {
      try {
        const user = await User.findOne({
          email: profile._json.email,
        });

        if (!user) {
          const newUser = await new User({
            name: profile.displayName,
            email: profile._json.email,
          }).save();
          done(null, newUser);
        } else {
          done(null, user);
        }
      } catch (error) {
        return done(error);
      }
    }
  )
);

passport.serializeUser((user, done) => {
  done(null, user._id);
});

passport.deserializeUser(async (id, done) => {

  const user = await User.findById(id).catch((err) => {
    done(err, null);
  });
  if (user) {
    done(null, user);
  }
});

This is the socket.io official GitHub repository where they showed how to handle passport.js cookie sessions and how to access user details. I followed them but I am unable to achieve my goal. I can't figure out what is my mistake. https://github.com/socketio/socket.io/blob/master/examples/passport-example/index.js#L76-L80//

0 Answers
Related