最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

node.js - Cookies are not sent when I run my Angular app in production mode - Stack Overflow

programmeradmin1浏览0评论

I am having issues sending cookies from my Angular app when I run it in production mode.

The steps I follow are the following:

  • I compile with: ng build --configuration=production
  • I run with: http-server -p 8080 .\dist\gero-universe-app\

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?

I am having issues sending cookies from my Angular app when I run it in production mode.

The steps I follow are the following:

  • I compile with: ng build --configuration=production
  • I run with: http-server -p 8080 .\dist\gero-universe-app\

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?

Share Improve this question asked Mar 16 at 16:21 GerardGerard 535 bronze badges 6
  • 1 You could start narrowing the problem down by using exactly the same origin, http-server -a localhost -p 4200. The difference is "Sec-Fetch-Site: cross-site", localhost and 192.168.1.38 are different sites. It's the expected behaviour with "sameSite: lax" – Estus Flask Commented Mar 16 at 17:36
  • @EstusFlask ow, it works thanks. But how can I make it work from any host? – Gerard Commented Mar 17 at 20:35
  • How will it run in prod deployment? If api and angular are different domains then you'll need to change to SameSite "none". If they are same domain/subdomain, so this fits "lax", then make sure they run locally the same way – Estus Flask Commented Mar 17 at 20:47
  • @EstusFlask But I already tried changing "SameSite": "none" and it didn't work as I was running it initially. What could be the cause of this? – Gerard Commented Mar 17 at 20:51
  • It's unknown under which conditions you used it. It requires secure and https at least, see developer.mozilla./en-US/docs/Web/HTTP/Reference/Headers/… – Estus Flask Commented Mar 17 at 20:56
 |  Show 1 more comment

1 Answer 1

Reset to default 0

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.

发布评论

评论列表(0)

  1. 暂无评论