简体   繁体   中英

GraphQL Secure Web Socket With Express

I am creating Express, Nuxt(SPA, basically Vue), GraphQL website with graphql subscriptions. My web sockets are supported only via http, which is very unfortunate. I can not figure out, how to use wss://mydomain/graphql/subscriptions. When I try to generate my.crt and.key and run it on localhost:3000, i get this error: ERR_SSL_VERSION_OR_CIPHER_MISMATCH. I am not sure if the openssl certificates are correct but I have tried like 10 guides and neither of them worked for me.

Also, I am deploying this web to Heroku, if that makes any difference. (when I push to heroku with this "https" config, the site does not even load).

One more thing: I am using graphql-compose-mongose to generate my schema, thus using Apollo is not possible (I think) because it requires TypeDef and Resolvers.

Here is my code. For socket on client I use "graphql-subscriptions-client".

const consola = require("consola");
const {Nuxt, Builder} = require("nuxt");
const cors = require("cors");
const {SubscriptionServer} = require("subscriptions-transport-ws");
const {execute, subscribe} = require("graphql");
// const {createServer} = require("http");
const {createServer} = require("https");
const {graphiqlExpress, graphqlExpress} = require("graphql-server-express");
const bodyParser = require("body-parser");


const fs = require("fs");
const path = require("path");

const server = express();

// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = process.env.NODE_ENV !== 'production';

// GraphQL schema
const schema = require("./graphql/schema");

async function start() {
  // Init Nuxt.js
  const nuxt = new Nuxt(config);

  const {host, port} = nuxt.options.server;

  // accept clients
  server.use('*', cors({origin: `https://${host}:${port}`}));

  // setup graphql server
  server.use('/graphql', bodyParser.json(), graphqlExpress({schema}));
  server.use('/graphiql', graphiqlExpress({
    endpointURL: '/graphql',
    subscriptionsEndpoint: `wss://${host}:${port}/subscriptions`
  }));

  // database connection
  await require("./database/connection");

  // generate GraphQL schema
  await require("../scripts/buildSchema");

  await nuxt.ready();
  // Build only in dev mode
  if (config.dev) {
    const builder = new Builder(nuxt);
    await builder.build()
  }

  // Give nuxt middleware to express
  server.use(nuxt.render);

  // wrap express server in web socket
  const serverOptions = {
    cert: fs.readFileSync(path.resolve(__dirname, './mydomain.crt')),
    key: fs.readFileSync(path.resolve(__dirname, './mydomain.key'))
  };


  // const webSocket = createServer(server);
  const webSocket = createServer(server, serverOptions);

  // start server
  webSocket.listen(port, () => {
    consola.ready({
      message: `Server listening on https://${host}:${port}`,
      badge: true
    });

    // Set up the WebSocket for handling GraphQL subscriptions
    new SubscriptionServer({
      execute,
      subscribe,
      schema
    }, {
      server: webSocket,
      path: '/subscriptions',
    });
  });
}

start();

Thank you for your answers.

Turns out Heroku does not provide free SSL. It costs 20$/month. So this can not be done for free.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM