Не удалось подключиться к конечной точке веб-сокета сервера Apollo, используя Nginx (с TLS) - PullRequest
1 голос
/ 16 января 2020

Я не могу запустить подписку (используя безопасный веб-сокет) через Nginx. Я получил сообщение с детской площадки: Could not connect to websocket endpoint wss://my_server/graphql. Please check if the endpoint url is correct.

Когда я смотрю в деталях, я вижу сообщение на вкладке Сеть: WebSocket is closed before the connection is established..

Я уже пытаюсь:

  • запустить ту же подписку непосредственно с сервера (без nginx и без использования TLS), и она работает.

  • запустить пинг-понг сервер websocket, и попробуйте сделать запрос, используя nginx и TLS, и это работает.

Моя конфигурация сервера apollo выглядит следующим образом:

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: true,
  playground: true,
  context: async ({ req, connection }): Promise<Partial<Context>> => {
    if (connection) {
      return connection.context;
    }
    //...
  },
  dataSources,
  subscriptions: {
    onConnect: async (connectionParams: {
      authorization?: string;
    }): Promise<Context> => {
      const token = connectionParams.authorization;
      //...
    },
    onDisconnect: async (_, context): Promise<void> => {
      //...
    }
  }
});

server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
  console.log(`? Server ready at ${url}`);
});

Моя Nginx конфигурация:

http {
  map $http_upgrade $connection_upgrade {
    default Upgrade;
    '' close;
  }

  ## Redirect all http to https
  server {
    listen [::]:80 default_server deferred;
    listen 80 default_server deferred;

    server_name _;

    location / {
      rewrite ^ https://$host$request_uri? permanent;
    }
  }

  ## SSL config

  ssl_certificate /config/fullchain.pem;
  ssl_certificate_key /config/privkey.pem;

  ssl_buffer_size 8k;

  ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;

  ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;

  ssl_ecdh_curve secp384r1;

  ssl_session_tickets off;
  ssl_session_timeout  10m;
  ssl_session_cache shared:SSL:10m;

  ssl_stapling on;
  ssl_stapling_verify on;

  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;
  add_header X-XSS-Protection "1; mode=block";

  server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;

    server_name my_server;

    root /var/www;
    index index.html;

    location / {
      try_files $uri /index.html =404;
    }
    location /static {
      add_header Cache-Control "public";
    }
    location /graphql {
      add_header X-Robots-Tag none;

      # this is the internal Docker DNS, cache only for 30s
      resolver 127.0.0.11 valid=30s;

      proxy_pass http://api:4000/graphql;

      proxy_set_header Proxy "";

      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";

      proxy_buffering off;
    }
  }
}

У меня заканчивается идей, если кто-то может мне помочь ?

...