NGINX+ssl\u验证\u客户端:socket.io保持连接

NGINX+ssl\u验证\u客户端:socket.io保持连接,ssl,nginx,socket.io,Ssl,Nginx,Socket.io,NGINX在其相关部分中是这样看的: listen 9443 ssl; server_name example.com; ssl_certificate mycert.crt; ssl_certificate_key mykey.key; ssl_client_certificate myca.pem; ssl_verify_client on; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection

NGINX在其相关部分中是这样看的:

listen 9443 ssl;
server_name example.com;

ssl_certificate      mycert.crt;
ssl_certificate_key  mykey.key;
ssl_client_certificate myca.pem;
ssl_verify_client on;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8443/;
socketio/node.js应用程序如下所示:

var restify                         = require('restify');
var server                          = restify.createServer();
var io                              = require('socket.io')    (server.server);
server.listen(8443, function () {
console.log('socket.io server listening at %s', server.url);
});
io.sockets.on('connection', function (socket) {
console.log("Client connected in io.sockets.on.connection");
socket.on('testfunc', function () {
    console.log("this is testfunc");
});
socket.on('disconnect', function(){
    console.log("Client disconnected");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="socket.io.js"></script>
<script>
$(document).ready(function() {
    var socket = io('https://example.com:9443', {secure: true});
    socket.on('connect', function () {
        socket.emit('testfunc');
    });
});
</script>
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570178744-3&sid=A_HsCwcklo30ZlifAAAA
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570179958-5&sid=gU1Nlv6asTakgE0KAAAB
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570181232-11&sid=Oy6ZnW3PZbK8cojHAAAC
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570182456-15&sid=-uK6YnSkYUyjPdI9AAAD
index.html如下所示:

var restify                         = require('restify');
var server                          = restify.createServer();
var io                              = require('socket.io')    (server.server);
server.listen(8443, function () {
console.log('socket.io server listening at %s', server.url);
});
io.sockets.on('connection', function (socket) {
console.log("Client connected in io.sockets.on.connection");
socket.on('testfunc', function () {
    console.log("this is testfunc");
});
socket.on('disconnect', function(){
    console.log("Client disconnected");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="socket.io.js"></script>
<script>
$(document).ready(function() {
    var socket = io('https://example.com:9443', {secure: true});
    socket.on('connect', function () {
        socket.emit('testfunc');
    });
});
</script>
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570178744-3&sid=A_HsCwcklo30ZlifAAAA
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570179958-5&sid=gU1Nlv6asTakgE0KAAAB
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570181232-11&sid=Oy6ZnW3PZbK8cojHAAAC
https://example.com:9443/socket.io/?EIO=3&transport=polling&t=1425570182456-15&sid=-uK6YnSkYUyjPdI9AAAD
新发现。问题是套接字请求没有发送客户端证书。而且,这个问题只存在于firefox中,我只对firefox和chrome感兴趣。在chrome中,它可以工作

只有在您指示请求发送客户端证书时,才能执行常规ajax请求:

$.ajax({
        url: 'https://example.com:9443/test',
        type: 'GET',
        xhrFields: {'withCredentials': true}
    }).success(function (value) {
        console.log(value)
        console.log('success');
    }).error(function () {
        console.log(arguments);
        console.log('error');
    });
上述请求在两种浏览器上都有效

现在,当进行套接字连接时,它会失败。它在Firefox中失败。但它在Chrome上工作。 我试图找出如何在socket.io上编写一个类似于ajax请求中withCredentials选项的选项。。但是没有运气。 另外:在Chrome中进行套接字连接时,无需设置任何withCredentials选项。听起来Chrome默认发送客户端证书

更有趣的是:当尝试建立套接字连接时,这两个浏览器使用什么协议?似乎两者都通过调用socket.io并将轮询作为传输来进行一些测试。然后两者都依赖于websocket。最后一项工作可以是:
firefox和chrome都使用websocket连接到服务器。然而,在chrome中,证书默认是发送的,而在firefox中则不是。

好消息。我找到了一个解决办法。以及问题的原因。当firefox仅将轮询或优先级轮询用作传输端口时,它就会失败。我的翻译是它在firefox中轮询时不发送证书。然而,在Chrome中它可以工作。因此,除了轮询之外,所有传输都可以在两种浏览器中使用。如果我进入socket.io.js并在设置xmlhttprequest时添加凭据,那么轮询仍然不起作用。恐怕这是关于浏览器的安全性。