socket.io 握手身份验证未定义,并且未在握手中显示身份验证

问题描述 投票:0回答:1

我正在使用 Socket.IO 服务器和客户端应用程序。以下是我的客户端代码:

this.socket = io("https://my-server-app.cloudapp.azure.com", {
  transports: ["websocket"],
  path: "/nodeserver/socket.io/",
  auth: {
    userId: userId,
    token: token,
  },
});

Socket.IO 服务器部署在 AKS 集群中。这是服务器端代码:

var io = require('socket.io')(app.listen(port), { path: "/nodeserver/socket.io/" });
io.sockets.on('connection', function (socket) {
  console.log("Handshake data:", socket.handshake);
  console.log(JSON.stringify(socket.handshake.auth));
});

问题 在本地运行应用程序时(localhost:8083),握手数据中的 auth 变量已正确填充,如日志中所示:

Handshake data: {
  headers: {
    host: 'localhost:8083',
    connection: 'Upgrade',
    pragma: 'no-cache',
    'cache-control': 'no-cache',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
    upgrade: 'websocket',
    origin: 'http://localhost:4200',
    'sec-websocket-version': '13',
    'accept-encoding': 'gzip, deflate, br, zstd',
    'accept-language': 'en-US,en;q=0.9',
    'sec-websocket-key': 'ATD5Ct1HLN3FDAajDfRfIQ==',
    'sec-websocket-extensions': 'permessage-deflate; client_max_window_bits'
  },
  time: 'Thu Dec 19 2024 11:36:44 GMT+0530 (India Standard Time)',
  address: '::1',
  xdomain: true,
  secure: false,
  issued: 1734588404811,
  url: '/nodeserver/socket.io/?EIO=4&transport=websocket',
  query: [Object: null prototype] { EIO: '4', transport: 'websocket' },
  auth: {
    userId: '[email protected]',
    token: 'mytoken'
  }
}

但是,当通过 AKS 部署的 URL (https://my-server-app.cloudapp.azure.com) 访问服务器时,握手数据中的 auth 字段丢失:

Handshake data: {
  headers: {
    host: 'https://my-server-app.cloudapp.azure.com',
    connection: 'Upgrade',
    pragma: 'no-cache',
    'cache-control': 'no-cache',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
    upgrade: 'websocket',
    origin: 'http://localhost:4200',
    'sec-websocket-version': '13',
    'accept-encoding': 'gzip, deflate, br, zstd',
    'accept-language': 'en-US,en;q=0.9',
    'sec-websocket-key': 'ATD5Ct1HLN3FDAajDfRfIQ==',
    'sec-websocket-extensions': 'permessage-deflate; client_max_window_bits'
  },
  time: 'Thu Dec 19 2024 12:20:20 GMT+0530 (India Standard Time)',
  address: '::1',
  xdomain: true,
  secure: false,
  issued: 1734588404811,
  url: '/nodeserver/socket.io/?EIO=4&transport=websocket',
  query: [Object: null prototype] { EIO: '4', transport: 'websocket' }
}

Socket.IO 服务器:

"socket.io": "^4.7.5"
和 Socket.IO 客户端:
"socket.io-client": "^4.8.1"
。 本地测试时auth对象正确传递。 通过 AKS 部署的 URL 访问时,它不会出现。

预期结果 auth 对象应包含在本地和部署环境的握手数据中。

如何确保在AKS环境中正确传输和记录身份验证数据?

node.js sockets websocket azure-aks
1个回答
0
投票

问题是

Socket.IO
在初始 WebSocket 握手中传输身份验证数据,但如果代理或负载均衡器删除这些标头或修改握手,则身份验证数据可能会丢失。

下面是我如何在

ingress.yaml
文件中使用代理设置标头的示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    appgw.ingress.kubernetes.io/backend-protocol: "http" 
    appgw.ingress.kubernetes.io/request-timeout: "60" 
    appgw.ingress.kubernetes.io/proxy-set-header: "Upgrade $http_upgrade"
    appgw.ingress.kubernetes.io/proxy-set-header.Connection: "upgrade" 
spec:
  ingressClassName: azure-application-gateway 
  rules:
    - host: my-server-app.cloudapp.azure.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-server-service
                port:
                  number: 3000

有关 Kubernetes 注释的详细信息,请参阅此链接

对于

service.yaml
,请使用以下配置:

apiVersion: v1
kind: Service
metadata:
  name: socketio-service
spec:
  selector:
    app: socketio
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
  type: ClusterIP

确保添加 cors 并确保 CORS 配置为允许来自所有域的请求:

  path: "/nodeserver/socket.io/",
  cors: {
    origin: "*",  
    methods: ["GET", "POST"],
    allowedHeaders: ["my-custom-header"],
    credentials: true,
  },
});

构建映像,使用 Azure 容器注册表对其进行标记,然后将其推送到注册表。

enter image description here 然后,使用此指南创建 Kubernetes 服务。使用 ACR 映像通过 YAML 文件将应用程序部署到 AKS 集群。

以下是示例

deployment.yaml
我使用的:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: socketio-server
  labels:
    app: socketio
spec:
  replicas: 2
  selector:
    matchLabels:
      app: socketio
  template:
    metadata:
      labels:
        app: socketio
    spec:
      containers:
      - name: socketio
        image:samopath.azurecr.io/newfolder2-app:latest

        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: production

enter image description here

使用 Azure Cloud Shell 连接到 AKS 群集,并使用 Kubernetes 运行应用程序。请按照此教程了解更多详细信息。

使用

kubectl get deployment
检查部署状态。使用
kubectl get pods

检查 Pod 状态

enter image description here 列出当前命名空间中的所有服务

kubectl get services
。 使用
kubectl expose deployment socketio-server --type=NodePort --port=3000 --target-port=3000
将其公开为 NodePort 服务。

enter image description here

更新

socketio-server
服务以使用
LoadBalancer
使用
kubectl patch service socketio-server -p '{"spec": {"type": "LoadBalancer"}}'
enter image description here 要查看特定 Pod 的日志,请使用:
kubectl logs socketio-server-865b857564-c2mxx

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.