[SOLVED] Does Anyone Have HTTPS and WSS Working in a Local Dev Environment?


#1

Does anyone have SSL working in a local dev environment in a way that supports both HTTPS and WS?


#2

I’m trying to get HTTPS and WSS (for Apollo subscriptions) working in my local dev environment. Even though I have them on two different ports, something seems to be forcing or redirecting the WSS calls to the HTTPS port.

Here’s my current code. For SSL access I have installed Meteor package nourharidy/meteor-ssl. I can use any comparable package or approach that people have found useful!

As required by nourharidy/meteor-ssl, in server/main.js I have:

`SSL('/path/to/private/server.key','/path/to/private/server.crt', 3100);`

My ROOT_URL environment variable is:

https://10.0.1.10:3100 //I’m using my Mac’s ip address so that another Mac can access it

In imports/startup/server/index.js I have:

//SET UP APOLLO QUERY / MUTATIONS / PUBSUB
const USING_HTTPS = true;
const httpProtocol =  USING_HTTPS ? "https" : "http"; 
const localHostString = '10.0.1.10' //I’m using my Mac’s ip address so that another Mac can access it

const METEOR_PORT = 3100;
const GRAPHQL_SUBSCRIPTION_PORT = 3200;
const subscriptionsEndpoint = `wss://${localHostString}:${GRAPHQL_SUBSCRIPTION_PORT}/subscriptions`;

const server = express();
server.use('*', cors({ origin: `${httpProtocol}://${localHostString}:${GRAPHQL_SUBSCRIPTION_PORT}` }));
server.use('/graphql', bodyParser.json(), graphqlExpress({
    schema
}));
server.use('/graphiql', graphiqlExpress({
    endpointURL: '/graphql',
    subscriptionsEndpoint: subscriptionsEndpoint
}));
// We wrap the express server so that we can attach the WebSocket for subscriptions
const ws = createServer(server);
ws.listen(GRAPHQL_SUBSCRIPTION_PORT, () => {
    console.log(`GraphQL Server is now running on ${httpProtocol}://${localHostString}:${GRAPHQL_SUBSCRIPTION_PORT}`);

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

Instead of being at https://10.0.1.10:3200/graphiql where it’s supposed to be, graphIql is at https://10.0.1.10:3100/graphiql!

In other words, graphIql loads up just fine on https://10.0.1.10:3100/graphiql, but if you go to https://10.0.1.10:3200/graphiql, you see 10.0.1.10 unexpectedly closed the connection.

If I put both HTTPS and WSS on the same port, e.g. 3100, I get an listen EADDRINUSE :::31001 error.

What’s a good server-side setup to get HTTPS and WSS in Meteor/Apollo?

Thanks in advance to all for any info.


#3

Solved it! It turns out my server setup was fine.

Server-side I was building the WSS url like so:

var websocketUri = Meteor.absoluteUrl('subscriptions').replace(/http/, 'ws').replace('3100', '3200');

The Meteor docs for absoluteUrl say:

The server reads from the ROOT_URL environment variable to determine where it is running.

In Webstorm I have ROOT_URL set to https://10.0.nn.nn:3100. But for some reason absoluteUrl was returning http://10.0.nn.nn:3000. I.e. it had the wrong port.

After correcting the port-- it’s working!


#4

UPDATE: I thought I had it solved when I posted a few days ago, but I was still missing something.

I’m now using ngrok to provide SSL to my dev system for use with HTTPS and WSS.

Here are a few details.

  • I run Meteor on localhost:3000.
  • I assign the value of “http://localhost:3000” to the ROOT_URL environment variable.
  • I run two simultaneous ngrok connections, one for HTTPS and one for WSS:
./ngrok http 3000 
./ngrok http 3200 
  • This gives me two ngrok urls, for example:

Forwarding https://9b785bd3.ngrok.io -> localhost:3000
Forwarding https://ec3d8027.ngrok.io -> localhost:3200

I access my app via the ngrok url, for example:

https://9b785bd3.ngrok.io

I build my HTTPS links and WSS links based on the ngrok addresses. For example:

const wssEndpoint = 'wss://ec3d8027.ngrok.io/subscriptions';

I hope this is helpful to others looking into this.