I am having issues sending cookies from my Angular app when I run it in production mode.
The steps I follow are the following:
In my app, I have a login that generates a cookie (in the backend) and returns it to the client. This cookie generation works correctly, and it is assigned in the browser both in Angular's dev mode and in Angular's prod mode.
The problem occurs when I make a request to the backend. In Angular's dev mode, the cookies are sent correctly, but for some reason, in the app's prod mode, the cookies are not sent to the backend.
In the headers of the dev mode request, the cookies appear:
GET /user/checkToken HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: es,es-ES;q=0.9,ca;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2Nzc1N2YwZGZlYzMxZDgzMWE3OWQ2ZGQiLCJpYXQiOjE3NDIxNDEzMTMsImV4cCI6MTc0MjE0ODUxM30.Ti2ST9SjUiCj7SW0zzp5WYSHgsnTVaa6-hE5XT-QGMg
Host: localhost:3000
If-None-Match: W/"e-3MDSGou3nIOvlBZElUyTiBbaRZY"
Origin: http://localhost:4200
Referer: http://localhost:4200/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
But in the headers of the prod mode request, the cookies do not appear:
GET /user/checkToken HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: es,es-ES;q=0.9,ca;q=0.8,en;q=0.7
Connection: keep-alive
Host: localhost:3000
Origin: http://192.168.1.38:8080
Referer: http://192.168.1.38:8080/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Storage-Access: active
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
In my code, when making a GET request, I set withCredentials to true, and this is the code snippet that makes the request but does not send the credentials:
public async checkToken(): Promise<boolean> {
try {
const response: UserCheckTokenResponse = await firstValueFrom(
this.http.get<UserCheckTokenResponse>(
`${environment.API_URL}/user/checkToken`,
{
withCredentials: true,
}
)
);
return response.valid;
} catch (error) {
throw error;
}
}
}
In the backend, I have the cookie generation like this:
res
.cookie("access_token", token, {
httpOnly: true,
secure: false,
maxAge: UserController.SESSION_TIME_H * 60 * 60 * 1000,
sameSite: lax,
})
.send({
userId: user._id,
username: user.username,
token: token,
});
In the backend, I have the CORS config like this, where the last three hosts are the production ones:
app.use(
cors({
origin: [
FRONT_END_HOST,
"http://127.0.0.1:8080",
"http://172.19.160.1:8080",
"http://192.168.1.38:8080",
],
credentials: true,
})
);
Would anyone be able to tell me why in dev mode the frontend is sending the cookies, but when I run it in prod mode, it does not?
It works when I start server with localhost http-server -a localhost -p 4200
It didn't work because SameSite was set to SameSite: lax, and since the backend server was running on localhost, which was not the same domain where the frontend was running, it didn't work.