[英]Can't establish a connection with javascript to a secure websocket server
我的开发环境是这样的:
我创建了一个新的 Laravel 应用程序来实现一个安全的 Websocket 服务器,并在客户端(Laravel 刀片文件)使用普通的 javascript 连接到它。 据我所见,websocket 服务器运行良好,但 web 浏览器无法连接,如下图所示:
我试过使用不同的 URL,有和没有端口号,但无济于事。 我使用openssl.exe工具创建了一个SSL证书和私钥文件,并将它们放在命令文件夹中以供测试。
这是我的安全 Websocket 服务器的句柄代码:
public function handle()
{
$loop = Factory::create();
$webSock = new SecureServer(
new Server('0.0.0.0:8090', $loop),
$loop,
array(
'local_cert' => 'certificate.crt',
'local_pk' => 'private.key',
'allow_self_signed' => TRUE,
'verify_peer' => FALSE
)
);
// Ratchet magic
$webServer = new IoServer(
new HttpServer(
new WsServer(
new WebSocketController()
)
),
$webSock
);
$loop->run();
}
我在httpd-ssl.conf
文件中的虚拟主机:
<VirtualHost *:443>
ServerName ssa
DocumentRoot "d:/web/app/ssa/public"
SSLEngine on
SSLCertificateFile "${SRVROOT}/conf/certificate.crt"
SSLCertificateKeyFile "${SRVROOT}/conf/private.key"
SSLVerifyClient none
SSLVerifyDepth 10
<Directory "d:/web/app/ssa/public">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
ProxyRequests Off
ProxyPass /wss/ ws://ssa:8090
</VirtualHost>
加载了 Apache 模块 proxy_module、proxy_http_module 和 proxy_wstunnel_module。 web 应用程序在 HTTPS 中运行。之前,它在 HTTP 和 WS 上运行并且一切正常,但我需要保护此应用程序并且我在连接到安全的 websocket 服务器时遇到问题。
我错过了什么吗?
我的Websocket服务器或者Apache配置有问题吗?
您肯定是在尝试连接到错误的目的地。 它说 wss:///ssa/wss/,但它可能应该是 wss://your.site.domain/ssa/wss/。
因此,让我们看一下前端代码并找出它的问题所在。
好的,正如@apokryfos 指出的那样,我试图通过 HTTPS 代理 websocket 服务器,但我做错了。
我将我的 websocket 服务器更改为非安全服务器,并对我的虚拟主机进行了以下更改:
<VirtualHost *:443>
ServerName ssa
DocumentRoot "d:/web/app/ssa/public"
SSLEngine on
SSLCertificateFile "${SRVROOT}/conf/certificate.crt"
SSLCertificateKeyFile "${SRVROOT}/conf/private.key"
SSLVerifyClient none
SSLVerifyDepth 10
<Directory "d:/web/app/ssa/public">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
Redirect /wss /wss/
ProxyPass /wss/ ws://127.0.0.1:8090/
ProxyPassReverse /ws/ wss://127.0.0.1:8090/
</VirtualHost>
在客户端,浏览器现在可以通过 HTTPS 端口联系后端 WS 服务器:
// The connection to the WebSocket Server.
var socket = new WebSocket("wss://ssa:443/wss/");
我从Apache Config: Websockets Proxy WSS request to WS backend得到这个解决方案
现在我得到了我的非安全 Websocket 服务器通过 HTTPS 发送/接收。当然,这不是我期望应用于我的需求的解决方案,但它确实有效。 我仍然希望找到一个正式的解决方案,在不使用代理机制的情况下将普通 JavaScript 客户端连接到安全的 Websocket 服务器 (wss://)。
为了不让更多信息使我的第一个答案复杂化,我在这里提供了毕竟对我真正有用的答案。
我创建了安全 Websocket 服务器,如下所示:
public function handle() {
$loop = Factory::create();
$webSock = new SecureServer(
new Server('0.0.0.0:8443', $loop),
$loop,
array(
'local_cert' => 'C:/wamp64/bin/apache/apache2.4.41/conf/server.crt',
'local_pk' => 'C:/wamp64/bin/apache/apache2.4.41/conf/server.key',
'allow_self_signed' => TRUE,
'verify_peer' => FALSE
)
);
$webServer = new IoServer(
new HttpServer(
new WsServer(
new WebSocketController()
)
),
$webSock
);
$loop->run();
}
注意我把端口号改成了8443(我不认为这有什么关系)并且还更改了新的证书和密钥文件,生成如下:
openssl req -config config.conf -new -x509 -out server.crt -days 3650
config.conf 文件是:
[req]
default_bits = 2048
encrypt_key = no
default_md = sha256
default_keyfile = server.key
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
C = KH
ST = Siem Reap
L = SR
O = AHC
OU = IT
CN = localhost
[bs_section]
CA=false
所有不同之处在于最后一行CA=false
表示我没有签署或充当证书颁发机构 (CA)。 这摆脱了MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY
消息。
然后,我去掉了在我的 httpd-ssl.conf 文件中定义代理的行:
<VirtualHost *:443>
ServerName ssa
DocumentRoot "d:/web/app/ssa/public"
SSLEngine on
SSLCertificateFile "${SRVROOT}/conf/server.crt"
SSLCertificateKeyFile "${SRVROOT}/conf/server.key"
SSLVerifyClient none
SSLVerifyDepth 10
<Directory "d:/web/app/ssa/public">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
#Redirect /wss /wss/
#ProxyPass /wss/ ws://127.0.0.1:8090/
#ProxyPassReverse /ws/ wss://127.0.0.1:8090/
</VirtualHost>
请注意,对于这个虚拟主机,我使用了与安全 Websocket 服务器相同的证书和密钥文件。
好的,这就是我的证书问题。
现在一切都按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.