0

I have a web application where the front end comprises of Angular application running on a domain say: http://localhost:4200 and the backend comprises of the NodeJs application running on a different domain say: http://localhost:3000.

Now I set a cookie from the backend whenever a user logs in successfully and that cookie contains a token. In http://localhost:4200(frontend) when the user logs in, the cookie appears only in the Network tab against the '/user/login' api request as shown in below image. But I don't see this cookie in the Applications tab even when I open a different browser tab and hit, http://localhost:3000(backend). I don't know the reason for this.

enter image description here

Next I want to ask how to set a cookie from http://localhost:3000(backend) such that when I send requests from http://localhost:4200(frontend) the cookie should also be sent with the request?

And is it possible to achieve this without sending the token in the response body instead of the cookie and then storing it in browser local storage at the frontend and using http interceptors in angular to add the token maybe in the headers for each request to protected routes?

Shri
  • 109
  • 9

1 Answers1

0

A CORS problem. Browser don't allow CORS requests. So you won't be able to access cookies across different domain:port.

You should allow CORS in nodejs application. Specifically Access-Control-Allow-Credentials: true header will ask browser to store cookie. Without this header in response it will reject cookie. You will only see them in network tab.

Don't use * in CORS headers instead use specific values else browser will not allow for security reasons. At angular you should use withCredentials configuration of httpClient.

If you don't want to go with cookie path then you should use token mechanism. After successful login return token and that token must be present in subsequent request. NodeJs JWT

Dhaval Gajjar
  • 2,508
  • 1
  • 2
  • 13
  • Hi Dhaval, I put this line: res.header("Access-Control-Allow-Credentials", true); in NodeJS but still I don't see the token set as cookie by the backend being sent to the backend on every request from the frontend. – Shri Apr 17 '23 at 11:08
  • Please add other 3 CORS headers and check do you see the cookie stored? While sending request from angular you need to also set `withCredentials` configuration of httpClient. – Dhaval Gajjar Apr 17 '23 at 11:17
  • I have added these cors headers:res.header("Access-Control-Allow-Origin", "http://localhost:4200"); res.header("Access-Control-Allow-Headers", "*"); res.header("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE"); res.header("Access-Control-Allow-Credentials", true); and also the {withCredentials: true} in the http post request but now I get this cors error: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response. – Shri Apr 17 '23 at 11:58
  • You should not use * for `Access-Control-Allow-Headers`. Instead use specific headers you want to allow. Check these answers https://stackoverflow.com/questions/25727306/request-header-field-access-control-allow-headers-is-not-allowed-by-access-contr – Dhaval Gajjar Apr 17 '23 at 12:04
  • Ok, I now set this res.header("Access-Control-Allow-Headers", "Content-Type"); and now I can see the cookie in the Applications tab at http://localhost:3000 in the browser. Now the only problem is that on refreshing the application I get logged out. I think I now need to send a request to the backend on app reload so that the cookie gets sent to the backend and the login state remains there until the token expires. – Shri Apr 17 '23 at 12:50
  • And I guess for security reasons the values for Access-Control-Allow-Origin and Access-Control-Allow-Headers have to be set explicitly instead of wildcard(*) while sharing cookies or headers across different domains. – Shri Apr 17 '23 at 12:53
  • Yes. For issue with refresh you need to adjust your angular code. It seems solution is done for your question. You can accept the answer for future reference for others. – Dhaval Gajjar Apr 17 '23 at 13:15