express-session with MongoStore working in Postman but not working in browser

91 views Asked by At

I am using MongoStore to store session. Following snippet initializes the usage of express-session and MongoStore

import session from "express-session";
import MongoStore from "connect-mongo";

app.use(session({
    secret: env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        maxAge: 60 * 60 * 1000 //one hour
    },
    rolling: true, //refresh cooking key as long as user is using the app
    store: MongoStore.create({
        mongoUrl: env.MONGO_CONNECTION_STRING
    })
}));

The server side code for login is as follows:

export const login: RequestHandler<unknown, unknown, loginBody, unknown> = async (req, res, next) => {
    const username = req.body.username;
    const password = req.body.password;

    try {
        if (!username || !password) {
            throw createHttpError(400, "Parameters missing");
        }

        const user = await Usermodel.findOne({ username: username }).select("+password +email").exec();

        if (!user) {
            throw createHttpError(401, "Invalid Credentials");
        }

        const passwordMatch = await bcrypt.compare(password, user.password as string);

        if (!passwordMatch) {
            throw createHttpError(401, "Invalid Credentials");
        }

        req.session.userId = user._id;
        // req.session.save();
        console.log("=======login and return========");
        console.log(req.session);
        console.log("=======login and return========");
        return res.status(201).json(user);

    } catch (error) {
        next(error);
    }
}

For which I get following output:

=======login and return========
Session {
  cookie: {
    path: '/',
    _expires: 2023-07-12T12:39:35.226Z,
    originalMaxAge: 3600000,
    httpOnly: true,
    secure: false
  },
  userId: new ObjectId("64ad134f22c49e34a7b08237")
}
=======login and return========

But in the middleware code, this userId is absent in request. Following is the snippet of middleware:

export const requiresAuth: RequestHandler = (req, res, next) => {
    console.log("========inside middleware==========");
    console.log(req.session);
    console.log("========inside middleware==========");
    if (req.session.userId) {
        next();
    } else {
        next(createHttpError(401, "User is not authenticated"));
    }
};

The output from middleware is:

========inside middleware==========
Session {
  cookie: {
    path: '/',
    _expires: 2023-07-12T12:39:35.420Z,
    originalMaxAge: 3600000,
    httpOnly: true,
    secure: false
  }
}
========inside middleware==========

As you can see clearly, property "userId" is missing from request.

I can also see records in "sessions" collection in MongoDB.

Ironically, everything works fine while using Postman client, but doesn't work in any browser.

1

There are 1 answers

40
Nazrul Chowdhury On BEST ANSWER

First Check the server-side CORS configuration and ensure that it allows credentials (cookies) to be included in the request. The server should respond with the appropriate CORS headers, including Access-Control-Allow-Origin and Access-Control-Allow-Credentials. 'Access-Control-Allow-Origin' should NOT BE '*'. Review and adjust the CORS configuration to allow the inclusion of credentials. then Include cookies with the request

export async function login(credentials: LoginBody): Promise<User> {
  const response = await fetch(BASE_URL + "/users/login", {
    method: "POST",
    headers: {
      "Content-type": "application/json",
    },
    body: JSON.stringify(credentials),
    credentials: 'include', // Include cookies with the request
  });

  return response.json();
}