I know I know, there are THOUSANDS of forums and questions where people get to make it work, and I've followed ALL of their suggestions, but I still cannot make it right and I'm literally wasting days on this, hopefully someone will help me out.
So, I have a controller in Spring, annotated :
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
From this controller, I'm returning the header for the set-cookie:
return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, my_cookie)
...
my_cookie is made this way:
ResponseCookie.from("cookie_name", value)
.path("/")
.httpOnly(true)
.secure(false)
.domain("localhost")
.build()
.toString();
Before you say anything, yes I've tried ALL of possible combinations that I've found on the internet:
secure false|true --> which as I understand true is only for https, so should be false for localhost tests
domain --> I've tried with localhost, localhost.org, localhost.test, my.localhost.org, no domain at all...
samesite --> either strict|none|lax , I've tried all of them in all combinations with other flags.
Spring is on port 8080.
Then, in react, on port 3000, I'm calling for authentication:
async function login(email, password) {
await fetch("http://localhost:8080/auth/login", {
method: "POST",
body: JSON.stringify({
email: email,
password: password,
}),
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
})
.then((response) => {
return response.json();
})
.then((json) => {
if (json.error) {
const error = json.error;
setShowError(true);
setError(errorMap.get(error));
return;
}
const token = json.payload.token;
const refreshToken = json.payload.refreshToken;
const name = json.payload.name;
setCookie("token", token);
setCookie("refreshToken", refreshToken);
setCookie("name", name);
})
.catch(() => {
setShowError(true);
setError("Error from server");
});
}
So, the 3 cookies get set, as I do it from react. But the set-cookie from spring does NOT get set on the Application --> localhost:3000 cookies. I instead get the cookie on postman. I know it's browser related, but I just want to point out that I correctly get the cookie set on postman.
Looking at the console in browser, the Set-Cookie header is there, and there is also the tab "Cookies" inside the request panel. It just gets no set on the browser's cookie side.
Moreover, when I call subsequent requests, I can't see the 3 cookies in requests. As I understand, cookies should be always included in requests towards BE, the browser does that automatically, right?
There seems to be wee details I'm missing, I know. I've tried those domains with .test, .org,... because I've read of the docs about Set-Cookie header in response and read about the double dots/3 dots etc... so I've tried them too.
Please help me out of this, It's been days trying different combinations. I also tried with Firefox, same results.
Solved it finally !!! Actually there were 2 mistakes: first one, I was missing credentials: "include" in react when calling for auth/login. Second mistake, I was setting the cookie with name "__Secure-", which is not preferrable for the browser. So I just took "__" out.
Settings that work that I'm using now:
ResponseCookie.from("Secure-name", cookieValue)
.path("/")
.httpOnly(true)
.secure(false)
.domain("localhost")
.build()
.toString();
localhost:3000 react
localhost:8080 spring
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
on Auth controller.
Moreover, all cookies are now sent correctly on subsequent requests.