使用 AWS ALB 时出现相同的站点 Cookie 问题 socket.io

Same site cookie issues on AWS ALB when using socket.io

提问人:TREX_SON 提问时间:11/10/2023 最后编辑:TREX_SON 更新时间:11/11/2023 访问量:57

问:

我的应用程序使用 Angular 作为前端,并使用 nodejs rest API 连接到 MongoDB。我的nodejs服务器应用程序运行在nginx容器上,其nginx.conf配置如下:

server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html/resume/browser;  
        try_files $uri $uri/ /index.html =404;
    }

    location /server {
        proxy_pass http://localhost:8083; # Pointing to your server
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /socket.io/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:8083;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

nodejs 应用程序使用 socket.io。我使用 docker 和 nginx 容器部署了应用程序,并且在本地一切正常。我将这些相同的设置移动到 AWS fargate,设置了安全组、ALB 侦听器和目标,一切正常,我可以在端口 80 上访问它,并使用 ALB 目标条件“/server”在端口 8083 上访问我的服务器。我的应用程序出现了,但问题是我的 socket.io 说它已连接,但我什么也没看到。然后我学会了我应该使目标具有粘性,我做到了,仍然没有错误,但后来我注意到了这个隐藏的错误:

Mark cross-site cookies as Secure to allow setting them in cross-site contexts
Cookies marked with SameSite=None must also be marked with Secure to allow setting them in a cross-site context. This behavior protects user data from being sent over an insecure connection.
Resolve this issue by updating the attributes of the cookie:
Specify SameSite=None and Secure if the cookie is intended to be set in cross-site contexts. Note that only cookies sent over HTTPS may use the Secure attribute.
Specify SameSite=Strict or SameSite=Lax if the cookie should not be set by cross-site requests.
1 cookie
Name    Domain & Path
AWSALBCORS  alb-ecs-service-957069708.us-east-2.elb.amazonaws.com/
202 requests
 ?userId=652f52d831c270a6dbee2323&EIO=4&transport=polling&t=Okt6Ilb
 ?userId=652f52d831c270a6dbee2323&EIO=4&transport=polling&t=Okt6JZu
 ?userId=652f52d831c270a6dbee2323&EIO=4&transport=polling&t=Okt6KiM
 ...

我尝试了以下方法,但没有任何效果 Socket.io 客户端

connectSocket(userId: string): void {
    this.socket = io(this.BASE_URL, {
      query: {
        userId: userId
      },
       withCredentials: true
    });
    
    console.log("here check", this.socket);
    const COOKIE_NAME = "AWSALB";//AWSALBCORS
    const COOKIE_NAME_CORS = "AWSALBCORS";//
    // Needed for ALB samesite cookie support issues
    this.socket.io.on("open", () => {
      this.socket.io.engine.transport.on("pollComplete", () => {
        const request = this.socket.io.engine.transport.pollXhr.xhr;
        const cookieHeader = request.getResponseHeader("set-cookie");
        if (!cookieHeader) {
          return;
        }
    
        const extraCookies: Record<string, string> = {}; 
        const COOKIE_NAME = "AWSALB"; 
    
        cookieHeader.forEach((cookieString: string) => {
          console.log(cookieString);
          if (cookieString.includes(`${COOKIE_NAME}=`)) {
            const cookie = parse(cookieString);
            extraCookies[COOKIE_NAME] = cookie[COOKIE_NAME];
          }
        });
    
        this.socket.io.opts.extraHeaders = {
          ...this.socket.io.opts.extraHeaders,
          cookie: Object.entries(extraCookies)
            .map(([key, value]) => `${key}=${value}`)
            .join("; "),
        };
      });
    });
    
  }
...

在服务器上: socket.io 服务器端

 this.socket = socketio(this.http, {
      cookie: {
        sameSite: 'none',
        secure: false  // Should be false for HTTP, true for HTTPS in production
      },
      cors: {
        origin: "*",
        // origin: config.FRONTEND_URI || 'http://localhost:4200',
        methods: ["GET", "POST"],
        credentials: true
      }
    })

没有任何效果,我已经用 5 多个资源研究了 100 天,我仍然可以找到解决方法。任何帮助都是值得赞赏的。

更新

在进行一些新的更改后,我现在收到此错误: ,它没有将AWSALB设置为这行代码的cookie:Refused to get unsafe header "set-cookie"


const cookieHeader = request.getResponseHeader("set-cookie");

节点.js aws-application-load-balancer socket.io nginx cookie

评论


答:

1赞 Rajesh P 11/10/2023 #1
 this.socket = socketio(this.http, {
  cookie: {
    sameSite:'None',
    secure: false  // Should be false for HTTP, true for HTTPS in production
  },
 ......
})

我正在考虑您在开发模式下运行应用程序,以便您可能已经保持安全:false,否则设置为 true。

尝试更改 sameSite:'None' 并查看结果

谢谢

评论

0赞 TREX_SON 11/11/2023
谢谢,我只是有时间看这个,我意识到我错误地使用了 nginx,所以我把它扔到了 /server 和 /socket.io 路径,我尝试了你的建议,现在我收到这个错误: 拒绝获取不安全的标头“set-cookie”,这意味着它无法将 AWSALB 设置为其代码行的 cookie: const cookieHeader = request.getResponseHeader("set-cookie");
0赞 TREX_SON 11/11/2023 #2

它终于在我的buildspec.yml中起作用了,我所做的只是提供 DNS 并让套接字 io 在 nginx 中使用默认路径 /socket.io/,而无需在客户端和服务器中设置路径