Home > Enterprise >  How to set a cookie through CORS
How to set a cookie through CORS

Time:10-18

I've reviewed other related posts and none are working for me. I am using vue on the client-side and node on the server-side.

I've tried the suggested method in other posts of using the cors library without success. One would think the below would allow me to send requests from my client localhost:8080 to my server, localhost:3000 but all posts are failing.

const cors = require("cors");
if (process.env.ENV !== "prod") {
  let corsOptions = {
    origin: ["http://localhost:8080"],
    credentials: true,
    optionsSuccessStatus: 200,
  };
  app.use(cors(corsOptions));
}

Here is my controller for setting the cookie.

router.route("/login").post(async (req, res) => {
  //Authenticate users
  const user = await Users.findOne({ where: { email: req.body.email } });

  if (user == null) {
    return res.status(400).send("Cannot find user!");
  }
  try {
    if (await bcrypt.compare(req.body.password, user.password)) {
      const userInfo = {
        username: user.username,
        email: user.email,
        age: user.age,
      };
      const accessToken = generateAccessToken(userInfo);

      const refreshToken = jwt.sign(userInfo, process.env.REFRESH_TOKEN_SECRET);
      res.cookie("token", accessToken, {
        maxAge: 300000,
        secure: true,
        httpOnly: true,
        sameSite: "none",
      });
      res.status(200).send("Logged in!");
    } else {
      res.send("Incorrect email or password!");
    }
  } catch {
    res.status(500).send();
  }
});

Every answer on this site more or less loops back to app.use(cors), for whatever reason it does not work for me.

CodePudding user response:

This may be because for cross domain cookies you are setting {sameSite: true} and {secure: true} but in your example you are doing this on http://localhost so it will not set any cookie. Please refer following link for requirements.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#samesitenone_requires_secure

Also set proper headers i.e. Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Access-Control-Allow-Headers

For reference you can use mkcert for secure connection on localhost.

I do also suggest to use same top level domain for frontend and backend and use subdomain.

One more thing to note here is that i think Chrome will not set the cookie if the domain has a port in it.so please give it a try.

CodePudding user response:

I managed to resolve the issue for any who may land here later. I moved up my declaration of cookieparser to above where I initialized my sequelize connection. I also added withCredentials to my axios post. In doing both my cookies are now both setting correctly and are able to be accesssed.

const express = require("express");
require("dotenv").config();
const cors = require("cors");
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const cookieParser = require("cookie-parser");
app.use(cookieParser());
const port = process.env.PORT || 8080;
const lib = require("./lib"); //This is all custom functions
const sql = require("./database");
      onSubmit() {
        let loginInfo = {
          email: email.value,
          password: password.value,
        };
        axios
          .post("http://localhost:3000/user/login", loginInfo, {
            withCredentials: true,
          })
          .then(() =>
            $q.notify({
              color: "green-4",
              textColor: "white",
              icon: "cloud_done",
              message: "Account successfully created!",
            })
          )
          .catch(() =>
            $q.notify({
              color: "red-5",
              textColor: "white",
              icon: "warning",
              message: "Email or username already taken!",
            })
          );
      },
  • Related