Search code examples
reactjstypescriptcookiesdeploymentmern

Cookies aren't working anymore after deploying MERN app


After deploying my MERN app the cookies aren't being set anymore after the user logs in. However, in my local environment everything is working fine. I have deployed both my frontend and backend on Render.

This is the error I am getting on the cookie: screenshot

This is my frontend

  async function handleLogin(e: React.FormEvent) {
    e.preventDefault();
    const response = await fetch("https://budgetfy.onrender.com/login", {
      method: "POST",
      body: JSON.stringify({
        username,
        password,
      }),
      headers: {
        "Content-Type": "application/json",
      },
      credentials: "include",
    });
    if (response.ok) {
      response.json().then((userInfo) => {
        setUserInfo(userInfo);
        setRedirect(true);
      });
    } else {
      //alert("Wrong credentials");
      setError(true);
    }
  }

This is my backend

app.use(
  cors({
    credentials: true,
    origin: "https://stevens-budgetfy.onrender.com",
  })
);

//API endpoint for login users
app.post("/login", async (req: Request, res: Response) => {
  console.log(req.body);
  const { username, password } = req.body;
  const userDoc = await User.findOne({ username });
  const passOk = bcrypt.compareSync(password, userDoc?.password);

  if (passOk) {
    jwt.sign(
      { username, id: userDoc?._id },
      process.env.JWT_SECRET,
      {},
      (err: Error, token: Response) => {
        if (err) throw err;
        res.cookie("token", token).json({
          id: userDoc?._id,
          username,
        });
      }
    );
  } else {
    res.status(400).json("wrong credentials");
  }
});

I have tried adding a proxy but this didn't seem to work. Is this the only solution?
I saw that when using vite you add the proxy to the vite.config.ts file instead of the package.json file (which is maybe why it didn't work the first time I did it).


Solution

  • You need to modify the res.cookie line in your backend to explicitly set the SameSite attribute to None.

            res.cookie("token", token, {
              secure: true, // Set to true if served over HTTPS
              sameSite: 'None',
            }).json({
              id: userDoc._id,
              username,
            });