Home > Software design >  res.cookie is not setting cookie in chrome browser
res.cookie is not setting cookie in chrome browser

Time:07-19

In development, I have a simple login page running on localhost (http://127.0.0.1:5500/index.html) and a minimal express server running on http://localhost:3003

I can see that the server is showing my access_token being sent in response headers but chrome browser is not setting it.

response headers are set

The application panel does not show any cookies being set. Application panel is empty

Here is my server:

const express = require("express");

const cors = require("cors");

const JWT = require("jsonwebtoken");
const cookieParser = require("cookie-parser");

const { json } = require("express");

const users = require("../users.json");

const SECRET = "1234";

const app = express();

app.use(
  cors({
    origin: "http://127.0.0.1:5500",
    credentials: true,
  })
);

app.use(express.json());
app.use(cookieParser());



app.post("/auth/login", (req, res) => {
  const { email, password } = req.body;

  // add pseudo validation
  if (email !== "********" && password !== "asdfasdf") {
    res.status(403);
    throw new Error("Bad user credentials");
  }

  const token = JWT.sign({ email }, SECRET);
  // console.log("token values:", token);

  res.cookie("access_token", token, {
    maxAge: 3600,
    httpOnly: false,
    secure: false,
    sameSite: "lax",
  });

  res.status(200).json({
    foo: "bar",
  });
});

On the frontend I am using fetch:

const loginForm = document.querySelector("#loginForm");

loginForm.addEventListener("submit", login);

function login(evt) {
  evt.preventDefault();
  const email = evt.target.email.value;
  const password = evt.target.psw.value;
  evt.target.reset();

  var headers = new Headers();
  headers.append("Content-Type", "application/json");
  headers.append("Accept", "application/json");

  return fetch("http://localhost:3003/auth/login", {
    method: "POST",
    mode: "cors",
    credentials: "include", // Don't forget to specify this if you need cookies
    headers: headers,
    body: JSON.stringify({ email, password }),
  }).then(
    (res) => {
      console.log(res);
    },
    (err) => {
      console.log(err);
    }
  );
}

I have tried multiple solutions posted for this same issue on SO:

  1. Adding mode: "cors" and credentials: "include" on the frontend
  2. Setting httpOnly to false, secure to false and also sameSite: "lax" on server to get past the new samesite chrome browser restrictions

And still nothing works! what am I doing wrong?

CodePudding user response:

Oh God!! localhost !== http://127.0.0.1

I had to change my fetch call to:

return fetch("http://http://127.0.0.1::3003/auth/login", { //<== this is the main change
    method: "POST",
    mode: "cors",
    credentials: "include", // Don't forget to specify this if you need cookies
    headers: headers,
    body: JSON.stringify({ email, password }),
  }).then(
    (res) => {
      console.log(res);
    },
    (err) => {
      console.log(err);
    }
  );

Cookies get set now. Special thanks to https://github.com/axios/axios/issues/1553#issuecomment-477761247

  • Related