Bey*_*ond 152 ssl https websocket node.js socket.io
我正在尝试使用我的SSL证书运行socket.io但是,它将无法连接.
我将我的代码基于聊天示例:
var https = require('https');
var fs = require('fs');
/**
 * Bootstrap app.
 */
var sys = require('sys')
require.paths.unshift(__dirname + '/../../lib/');
/**
* Module dependencies.
*/
var express = require('express')
  , stylus = require('stylus')
  , nib = require('nib')
  , sio = require('socket.io');
/**
 * App.
 */
var privateKey = fs.readFileSync('../key').toString();
var certificate = fs.readFileSync('../crt').toString();
var ca = fs.readFileSync('../intermediate.crt').toString();
var app = express.createServer({key:privateKey,cert:certificate,ca:ca });
/**
 * App configuration.
 */
...
/**
 * App routes.
 */
app.get('/', function (req, res) {
  res.render('index', { layout: false });
});
/**
 * App listen.
 */
app.listen(443, function () {
  var addr = app.address();
  console.log('   app listening on http://' + addr.address + ':' + addr.port);
});
/**
 * Socket.IO server (single process only)
 */
var io = sio.listen(app,{key:privateKey,cert:certificate,ca:ca});
...
如果我删除SSL代码它运行正常,但是有了它我收到了http://domain.com/socket.io/1/?t=1309967919512的请求
请注意,它不会尝试https,这会导致失败.
我正在测试chrome,因为它是此应用程序的目标浏览器.
如果这是一个简单的问题,我很抱歉,我是node/socket.io新手.
谢谢!
kan*_*aka 181
使用安全URL进行初始连接,即使用"https://"代替"http://".如果选择了WebSocket传输,那么Socket.IO也应该自动使用"wss://"(SSL)进行WebSocket连接.
更新:
您还可以尝试使用'secure'选项创建连接:
var socket = io.connect('https://localhost', {secure: true});
emo*_*nik 42
这就是我设法用express来设置的方法:
var fs = require( 'fs' );
var app = require('express')();
var https        = require('https');
var server = https.createServer({
    key: fs.readFileSync('./test_key.key'),
    cert: fs.readFileSync('./test_cert.crt'),
    ca: fs.readFileSync('./test_ca.crt'),
    requestCert: false,
    rejectUnauthorized: false
},app);
server.listen(8080);
var io = require('socket.io').listen(server);
io.sockets.on('connection',function (socket) {
    ...
});
app.get("/", function(request, response){
    ...
})
 我希望这能节省一些人的时间.
更新:对于使用let加密的人使用此
var server = https.createServer({ 
                key: fs.readFileSync('privkey.pem'),
                cert: fs.readFileSync('fullchain.pem') 
             },app);
Kuf*_*Kuf 31
同样,如果您的服务器支持两者http,https您可以使用以下方式连接:
var socket = io.connect('//localhost');
以自动检测浏览器方案,并使用HTTP/HTTPS连接相应.在https中,默认情况下传输将受到保护,如使用连接
var socket = io.connect('https://localhost');
将使用安全的Web套接字 - wss://(这   {secure: true}是多余的).
有关如何使用同一节点服务器轻松提供http和https的详细信息,请查看此答案.
如果您的服务器认证文件不受信任(例如,您可以使用java中的keytool命令自行生成密钥库),则应添加额外选项rejectUnauthorized
var socket = io.connect('https://localhost', {rejectUnauthorized: false});
根据您的需要,您可以允许安全和不安全的连接,并且仍然只使用一个 Socket.io 实例。
您只需实例化两台服务器,一台用于 HTTP,另一台用于 HTTPS,然后将这些服务器附加到 Socket.io 实例。
服务器端 :
// needed to read certificates from disk
const fs          = require( "fs"    );
// Servers with and without SSL
const http        = require( "http"  )
const https       = require( "https" );
const httpPort    = 3333;
const httpsPort   = 3334;
const httpServer  = http.createServer();
const httpsServer = https.createServer({
    "key" : fs.readFileSync( "yourcert.key" ),
    "cert": fs.readFileSync( "yourcert.crt" ),
    "ca"  : fs.readFileSync( "yourca.crt"   )
});
httpServer.listen( httpPort, function() {
    console.log(  `Listening HTTP on ${httpPort}` );
});
httpsServer.listen( httpsPort, function() {
    console.log(  `Listening HTTPS on ${httpsPort}` );
});
// Socket.io
const ioServer = require( "socket.io" );
const io       = new ioServer();
io.attach( httpServer  );
io.attach( httpsServer );
io.on( "connection", function( socket ) {
    console.log( "user connected" );
    // ... your code
});
客户端 :
var url    = "//example.com:" + ( window.location.protocol == "https:" ? "3334" : "3333" );
var socket = io( url, {
    // set to false only if you use self-signed certificate !
    "rejectUnauthorized": true
});
socket.on( "connect", function( e ) {
    console.log( "connect", e );
});
如果您的 NodeJS 服务器与您的 Web 服务器不同,您可能需要设置一些 CORS 标头。所以在服务器端,替换:
const httpServer  = http.createServer();
const httpsServer = https.createServer({
    "key" : fs.readFileSync( "yourcert.key" ),
    "cert": fs.readFileSync( "yourcert.crt" ),
    "ca"  : fs.readFileSync( "yourca.crt"   )
});
和:
const CORS_fn = (req, res) => {
    res.setHeader( "Access-Control-Allow-Origin"     , "*"    );
    res.setHeader( "Access-Control-Allow-Credentials", "true" );
    res.setHeader( "Access-Control-Allow-Methods"    , "*"    );
    res.setHeader( "Access-Control-Allow-Headers"    , "*"    );
    if ( req.method === "OPTIONS" ) {
        res.writeHead(200);
        res.end();
        return;
    }
};
const httpServer  = http.createServer( CORS_fn );
const httpsServer = https.createServer({
        "key" : fs.readFileSync( "yourcert.key" ),
        "cert": fs.readFileSync( "yourcert.crt" ),
        "ca"  : fs.readFileSync( "yourca.crt"   )
}, CORS_fn );
当然,添加/删除标题并根据您的需要设置标题的值。