1

I’m trying to deploy a MERN stack website that I’ve been working on locally. While everything works fine locally, after deploying to Render and Vercel, I can’t access session data through req.session. I will share the code details below.

Some of app.ts file for backend:

const app = express()
app.set("trust proxy", 1)
app.use(cors({
  origin: ["https://frontend.vercel.app", "http://localhost:3000"],
  credentials: true
}))
app.use(morgan("dev"))
app.use(express.json()) 
export const Session = session({ 
    secret:env.SESSION_SECRET,
    resave: false,              
    saveUninitialized: false,
    cookie: {
        maxAge: 720 * 60 * 60 * 1000,
        httpOnly: true,
        secure: env.EGE === "production", 
        sameSite: env.EGE === "production" ? "none" : "lax"      
    },
    rolling: true,              
    store: MongoStore.create({
        mongoUrl: env.MONGO_CONNECTION_STRING
    }),
})
app.use(Session)

login:RequestHandler function for backend:

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, "missing parameters")
        }
        const user= await UserModel.findOne({username: username}).select("password").exec()

        if(!user){
            throw createHttpError(400, "invalid credentials")
        }
        const passwordMatch = await bcrypt.compare(password, user.password)

        if(!passwordMatch){
            throw createHttpError(400, "invalid credentials")
        }
        
        req.session.userId= user._id
        req.session.save(err => {
            if (err) return next(err);
            res.status(200).json(user);
        })
        // res.status(200).json(user)

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

login fetch function for frontend:

async function fetchData(input: RequestInfo, init?: RequestInit) {
    const response = await fetch(input, init)
    if(response.ok){
        return response
    }
    else{
        try {
            const errorBody= await response.json()
            const errorMessage= errorBody.error
            throw new Error(errorMessage)
        } catch (error) {
            throw new Error("failed to parse error")
        }
    } 
}
export async function login(credentials:LoginCredentials): Promise<User> {
    const response = await fetchData(`${process.env.REACT_APP_BACKEND_URL}/api/users/login`,{
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        credentials: "include",
        body: JSON.stringify(credentials)
    })
    return response.json()
  }

After deploying via Vercel and Render, I login to the site and the login function returns the correct response. Then I use console.log(req.session) to check if I can see the userId data, but I can only see the cookie inside req.session. In the MongoDB sessions collection, the stored data includes the userId, but in the Render logs, the session does not contain the userId. When I login locally, req.session contains both the cookie and the userId.

Render/Vercel log session + mongodb session

local log session + mongodb session

As seen in the images above, the session in the Render logs does not include the userId, but the userId is visible in the MongoDB session data. When I run the site locally, the userId appears in both the Node.js logs and the MongoDB session data. I have tried adjusting CORS and proxy settings but couldn’t find a solution. I would appreciate any help.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.