Victor Ezequiel
Victor Ezequiel

Reputation: 67

Socket.io with connection on node server with HTTPS and NGINX

I'm trying to work with the socket but when connecting the system in production, I believe that due to SSL certificates it ends up giving some conflict and this error pops:

Mixed Content: The page at 'https://myapp.com' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://myapp.com:3001/socket.io/?EIO=3&transport=polling&t=N4Tk_Lq'. This request has been blocked; the content must be served over HTTPS.

I tried several solutions found on the internet, but none of it worked so I asked the question here.

Config on back-end:

    const clientServer = require("http").Server(client.app);
    global.io = require('./socketio.js').init(clientServer, {
        pingInterval: 10,
        pingTimeout: 5,
    });

    clientServer.listen(3001, () => {
        console.log("client ON");
    });

Config on front-end:

const config: SocketIoConfig = { url: 'http://myapp.com:3001', options: {} };

Nginx:

 location /client/v1 {
    proxy_pass http://localhost:3001;
    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;
  }

Upvotes: 0

Views: 1582

Answers (2)

Victor Ezequiel
Victor Ezequiel

Reputation: 67

I managed to put the node server to https, changing also in nginx

on the angular client side it looked like this (front-end)

const config: SocketIoConfig = { url: 'https://myapp.com:3001', options: {secure: true} };

for some reason it didn't work with https://myapp.com/client/v1

on the server side with nodejs it looks like this:

var privateKey = fs.readFileSync('/etc/letsencrypt/live/myapp.com/privkey.pem', 'utf8').toString();
var certificate = fs.readFileSync('/etc/letsencrypt/live/myapp.com/cert.pem', 'utf8').toString();
var chain = fs.readFileSync('/etc/letsencrypt/live/myapp.com/chain.pem').toString();
var options = { key: privateKey, cert: certificate, chain: chain }; 

Starting server like that:

const clientServer = require("https").Server(options,client.app);
    global.io = require('./socketio.js').init(clientServer, {
        pingInterval: 10,
        pingTimeout: 5,
    });

    clientServer.listen(3001, () => {
        console.log("client ON");
    });

and in nginx I had to put the "s" in the proxy_pass:

location /client/v1 {
    proxy_pass http://localhost:3001;
    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;
  }

Upvotes: 1

SpaceKatt
SpaceKatt

Reputation: 1411

If NGINX is acting as a reverse proxy, then the port 3001 is never exposed.

Try appending the /client/v1 endpoint to your domain name in the config on the front-end:

const config: SocketIoConfig = { url: 'https://myapp.com/client/v1', options: {} };

Or, if you need to include the .br...

const config: SocketIoConfig = { url: 'https://myapp.com.br/client/v1', options: {} };

Upvotes: 0

Related Questions