如何在本地主机上使用Nginx反向代理来使用Node。

huangapple go评论71阅读模式
英文:

How to use node on localhost with nginx reverse proxy

问题

我理解的是,在这个设置中,我在本地主机上运行了一个 WebSocket 服务器(node),并使用位于其前面的 Nginx 反向代理来处理握手和持久连接。

我遇到的问题是:

混合内容:页面加载于 HTTPS,但尝试连接到不安全的 WebSocket 端点 'ws://domain.com:8020/'。此请求已被阻止;该端点必须通过 WSS 可用。

未捕获的 DOM 异常:无法构造 'WebSocket':不安全的 WebSocket 连接可能不会在加载了 HTTPS 的页面上启动。

所以,我是否也需要为 WebSocket 获取另一个证书?

以下是 Nginx 配置:

http {
  ...

  upstream websocket {
    server 127.0.0.1:8080;
  }

  server {
    listen 8020;

    location / {
      proxy_pass http://websocket;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_set_header Host $host;
      proxy_read_timeout 1d;
      proxy_send_timeout 1d;
    }
  }

  server {
    listen 80 default_server;
    listen [::]:80 default_server;

    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    ssl_certificate     /location/cert.pem;
    ssl_certificate_key /location/cert-key.pem;

    root /var/www/html/app;

    index index.php index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {		
      try_files $uri $uri/ =404;
    }
  }
}

Node:

const wss = new WebSocketServer({port: 8080})

客户端:

const socket = new WebSocket('wss://domain.com:8020')

需要注意的是,使用 http 时一切正常运行,只是不确定如何使其在 https 下正常工作。

英文:

My understanding is that, in this setup I run a websocket server(node) on localhost and use the Nginx reverse proxy that sits in front of it to handle the handshake and persistent connection.

The problem that I'm facing is:

> Mixed Content: The page at 'domain.com' was loaded over HTTPS,
> but attempted to connect to the insecure WebSocket endpoint
> 'ws://domain.com:8020/'. This request has been blocked; this endpoint
> must be available over WSS.
>
> Uncaught DOMException: Failed to construct 'WebSocket': An insecure
> WebSocket connection may not be initiated from a page loaded over
> HTTPS.

So, do I need to have another certificate for the websocket as well ?

Here is the nginx config:

http {
...

upstream websocket {
	server 127.0.0.1:8080;
}

	server {
		listen 8020;

		location / {
			proxy_pass http://websocket;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection $connection_upgrade;
			proxy_set_header Host $host;
			proxy_read_timeout 1d;
			proxy_send_timeout 1d;
		}
	}
	
	server {
		listen 80 default_server;
		listen [::]:80 default_server;

		listen 443 ssl default_server;
		listen [::]:443 ssl default_server;

		ssl_certificate     /location/cert.pem;
		ssl_certificate_key /location/cert-key.pem;

		root /var/www/html/app;

		# Add index.php to the list if you are using PHP
		index index.php index.html index.htm index.nginx-debian.html;

		server_name _;

		location / {		
			# First attempt to serve request as file, then
			# as directory, then fall back to displaying a 404.
			try_files $uri $uri/ =404;
		}

	}


}
----------------------------------------
Node:
const wss = new WebSocketServer({port: 8080})

Client:
const socket = new WebSocket('ws://domain.com:8020')

Should note that everything works while using http, just not sure how to make it work with https.

答案1

得分: 0

发现了,只需将ssl_certificatessl_certificate_key移到http块中,在nginx中是这样继承它们的。

还要在js中将ws更改为wss

http {
    ...

    ssl on; # 或者使用 listen ssl on 已经过时

    ssl_certificate     /location/cert.pem;
    ssl_certificate_key /location/cert-key.pem;
    
    ...
    
    upstream websocket {
        server 127.0.0.1:8080;
    }

    server {
        listen 8020;

        location / {
            proxy_pass http://websocket;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
            proxy_read_timeout 1d;
            proxy_send_timeout 1d;
        }
    }
    
    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        root /var/www/html/app;

        index index.php index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {		
            try_files $uri $uri/ =404;
        }
    }
}
Node:
const wss = new WebSocketServer({port: 8080})

Client:
const socket = new WebSocket('wss://domain.com:8020')
英文:

Found it, just hat to move the ssl_certificate and sl_certificate_key in the http block, new to nginx but I'm guessing that way they get inherited in both server blocks.

Also change ws to wss in js.

http {
...

ssl on; # or use listen ssl on is deprecated

ssl_certificate     /location/cert.pem;
sl_certificate_key /location/cert-key.pem;


upstream websocket {
	server 127.0.0.1:8080;
}

	server {
		listen 8020;

		location / {
			proxy_pass http://websocket;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection $connection_upgrade;
			proxy_set_header Host $host;
			proxy_read_timeout 1d;
			proxy_send_timeout 1d;
		}
	}
	
	server {
		listen 80 default_server;
		listen [::]:80 default_server;

		listen 443 ssl default_server;
		listen [::]:443 ssl default_server;

		root /var/www/html/app;

		# Add index.php to the list if you are using PHP
		index index.php index.html index.htm index.nginx-debian.html;

		server_name _;

		location / {		
			# First attempt to serve request as file, then
			# as directory, then fall back to displaying a 404.
			try_files $uri $uri/ =404;
		}

	}


}
----------------------------------------
Node:
const wss = new WebSocketServer({port: 8080})

Client:
const socket = new WebSocket('wss://domain.com:8020')

huangapple
  • 本文由 发表于 2023年6月5日 23:57:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76408142.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定