Сервер WebSocket не работает с SSL
У меня есть рабочее приложение чата, использующее websockets. Я хочу сделать еще один шаг и включить шифрование в своих подключениях, однако, когда я переключаю HTTP-сервер с https, один из которых запускает мои подключения.
Я создал самозаверяющий сертификат, который я использую на всех моих сайтах (под тем же TLD, что означает, что это подстановочный знак). Я могу подтвердить, что это действительный сертификат, поэтому проблемы не должно быть.
Это то, что работает (незашифрованное)
var webSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function() {});
server.listen(webSocketsServerPort, function () {
log("system", "Server is listening on port " + webSocketsServerPort);
});
var wsServer = new webSocketServer({
httpServer: server
});
Используя это, теперь я могу подключиться к ws://my.domain:port
.
Это то, что работает не
var webSocketServer = require('websocket').server;
var http = require('https');
var fs = require('fs');
var server = http.createServer({
key: fs.readFileSync("path/to/host.key"),
cert: fs.readFileSync("path/to/host.pem")
});
server.listen(webSocketsServerPort, function () {
log("system", "Server is listening on port " + webSocketsServerPort);
});
var wsServer = new webSocketServer({
httpServer: server
});
С помощью этого кода сервер запускается также, я вижу сообщение журнала "Сервер прослушивает..", но когда я пытаюсь подключиться в wss://my.domain:port
, соединение не может быть установлено.
Я добавил исключение в свой браузер для сертификата, потому что моя клиентская страница и адрес сервера веб-сервера находятся под одним и тем же доменом и поддоменом.
В чем может быть проблема?
Ответы
Ответ 1
Плохая практика в сочетании с плохими привычками ведения журналов была причиной проблемы.
При открытии нового соединения произошла проверка, выполняемая для проверки происхождения запроса, который был там hardcoded http://
, и поскольку я запрашивал его с защищенной страницы (https://
), проверка больше не передавалась и соединения были невозможны.
Ответ 2
Недостаточно добавить сайт, из которого вы хотите подключиться к веб-расписанию в качестве исключения. Перейдите на сайт https://my.domain:port
(адрес веб-сайта) и добавьте его в качестве исключения. (Это, безусловно, необходимый шаг в Firefox)
В качестве альтернативы вы можете импортировать сертификат в диспетчере сертификатов в полномочия.
Изменить: Я могу рассказать вам, что работает для меня.
> openssl genrsa -out key.pem
> openssl req -new -key key.pem -out csr.pem
> openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
установив общее имя как localhost
в main.js
var https = require('https');
var ws = require('websocket').server;
var fs = require('fs');
var options = {
key:fs.readFileSync('key.pem'),
cert:fs.readFileSync('cert.pem')
};
var server = https.createServer(options,
function(req,res){res.writeHeader(200);res.end();});
server.listen(8000);
var wss = new ws({httpServer:server});
wss.on('request',function(req){
req.on('requestAccepted',function(conn){
conn.on('message',function(msg){
conn.send(msg.utf8Data + " received");
});
})
req.accept(null,req.origin);
});
затем в браузере (Firefox) в https://localhost:8000
(добавлен сертификат как исключение)
var ws = new WebSocket('wss://localhost:8000/')
ws.onmessage = function(msg){console.log(msg.data)}
ws.send("test")
и получил test received
.