0

I am having a basic authentication setup which works fine in localhost. When the client side send a request to server, it assigns back the jwt token as a cookie. When I run this simple login in production, the register setup is working but the cookie is not assigned to the client site.
Client side: functions.js:

const { axios } = require("./axios");
const registerFunc = (name, email, password, ageName, ageDate) => {
  return userServer
    .post(
      "/register",
      {
        name: name,
        email: email,
        password: password,
        ageName: ageName,
        ageDate: ageDate,
      },
      {
        withCredentials: true,
      }
    )
    .then((res) => {
      return "success";
    })
    .catch((err) => {
      return err.response.data;
    });
};

Server side: index.js:

const express = require("express");
const cors = require("cors");
require("dotenv").config();
const cookieParser = require("cookie-parser");
const authRoutes = require("./routes/auth");
const itemRoutes = require("./routes/item");

const app = express();
app.use(
  cors({
    origin: [
      process.env.WEBSITE1_URL,
      process.env.WEBSITE2_URL,
      process.env.WEBSITE3_URL,
    ],
    credentials: true,
    exposedHeaders: ["set-cookie"],
  })
);
app.use(express.json());
app.use(cookieParser());
app.use("/api/user", authRoutes);
app.use("/api/item", itemRoutes);

app.listen(5000, () => console.log("Server running"));

Server side: routes/auth.js:

router.post("/register", async (req, res) => {
  //Validate
  const { error } = registerValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);

  const emailExist = await User.findOne({ email: req.body.email });
  if (emailExist) return res.status(400).send("Email already exists");

  //Hash Password
  const salt = await bcrypt.genSalt(10);
  const hashedPassword = await bcrypt.hash(req.body.password, salt);

  User.create(
    {
      name: req.body.name,
      email: req.body.email,
      password: hashedPassword,
      ageName: req.body.ageName,
      ageDate: req.body.ageDate,
      loggedIn: true,
    },
    (err, data) => {
      if (err) {
        res.status(400).send(err);
      } else {
        const token = jwt.sign({ _id: data._id }, process.env.TOKEN_SECRET);
        const cookieExpiry = new Date();
        cookieExpiry.setYear(cookieExpiry.getYear() + 8000);
        res
          .cookie("authToken", token, {
            domain: "https://<client-url>.vercel.app",
            httpOnly: true,
            expires: cookieExpiry,
            secure: true,
          })
          .cookie("loggedIn", true, {
            domain: "https://<client-url>.vercel.app",
            expires: cookieExpiry,
            secure: true,
          })
          .send("Registerd");
      }
    }
  );
});

EDIT:
In the console, it gives this warning: enter image description here The attempt to set a cookie via a Set-Cookie was blocked because its Domain attribute was invalid with regards to the current host url

Any help is greatly appreciated!
Thanks!

Ajit Kumar
  • 367
  • 1
  • 10
  • 35

1 Answers1

0

Try adding exposedHeaders: ["set-cookie"], to the object you pass to cors. See this answer to a similar question: Does Axios support Set-Cookie? Is it possible to authenticate through Axios HTTP request?

CascadiaJS
  • 2,320
  • 2
  • 26
  • 46