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.
The application panel does not show any cookies being set.
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:
- Adding
mode: "cors"
andcredentials: "include"
on the frontend - Setting
httpOnly
tofalse
,secure
tofalse
and alsosameSite: "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