wss 比 ws 多了一层证书校验,理论上我们只要在 websocket 服务器前面加一层 ssl 的认证就可以了。
服务器配置
代码直接用 QT 官方的栗子:
链接: SSL 回显服务器示例
打开 sslechoserver.cpp 文件,看构造函数就可以了
//! [constructor]
SslEchoServer::SslEchoServer(quint16 port, QObject *parent) :
QObject(parent),
m_pWebSocketServer(nullptr)
{
m_pWebSocketServer = new QWebSocketServer(QStringLiteral("SSL Echo Server"),
QWebSocketServer::SecureMode,
this);
QSslConfiguration sslConfiguration;
QFile certFile(QStringLiteral(":/localhost.cert"));
QFile keyFile(QStringLiteral(":/localhost.key"));
certFile.open(QIODevice::ReadOnly);
keyFile.open(QIODevice::ReadOnly);
QSslCertificate certificate(&certFile, QSsl::Pem);
QSslKey sslKey(&keyFile, QSsl::Rsa, QSsl::Pem);
certFile.close();
keyFile.close();
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfiguration.setLocalCertificate(certificate);
sslConfiguration.setPrivateKey(sslKey);
m_pWebSocketServer->setSslConfiguration(sslConfiguration);
if (m_pWebSocketServer->listen(QHostAddress::Any, port))
{
qDebug() << "SSL Echo Server listening on port" << port;
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
this, &SslEchoServer::onNewConnection);
connect(m_pWebSocketServer, &QWebSocketServer::sslErrors,
this, &SslEchoServer::onSslErrors);
}
}
//! [constructor]
“:/localhost.cert” 和 “:/localhost.key” 就是 SSL 认证的证书和密钥,填对应的文件路径就可以了。
使用 wss 有个小坑,创建 websocket 的时候,模式要用安全模式 QWebSocketServer::SecureMode ,使用 QWebSocketServer::NoSecureMode 非安全模式的话,会连不上。
如果证书和密钥是 “.p12” 文件的话可以这样配置,“123456” 是 “.p12” 文件的密码。
//! [constructor]
SslEchoServer::SslEchoServer(quint16 port, QObject *parent) :
QObject(parent),
m_pWebSocketServer(nullptr)
{
m_pWebSocketServer = new QWebSocketServer(QStringLiteral("SSL Echo Server"),
QWebSocketServer::SecureMode,
this);
QFile certFile("./keystore.p12");
certFile.open(QFile::ReadOnly);
QSslCertificate certificate;
QSslKey key;
QList<QSslCertificate> importedCerts;
bool imported = QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString("123456"));
qDebug() << "Imported: " << imported;
QSslConfiguration conf = m_pWebSocketServer->sslConfiguration();
conf.setCaCertificates(importedCerts);
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
conf.setLocalCertificate(certificate);
conf.setPrivateKey(key);
m_pWebSocketServer->setSslConfiguration(conf);
if (m_pWebSocketServer->listen(QHostAddress::Any, port))
{
qDebug() << "SSL Echo Server listening on port" << port;
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
this, &SslEchoServer::onNewConnection);
connect(m_pWebSocketServer, &QWebSocketServer::sslErrors,
this, &SslEchoServer::onSslErrors);
}
}
//! [constructor]
客户端访问
客户端连接不用加证书,把连接的 ws 改成 wss 就可以了。
测试连接的话,可以直接在搜索引擎搜索 wss 测试工具。浏览器访问 wss 也有坑,如果证书是自签的,会访问失败。因为浏览器 “允许运行不安全的本地服务器” 选项默认是禁止的,需要把这个选项打开才能连接。
chrome 浏览器输入:
chrome://flags/#allow-insecure-localhost
把 allow-insecure-localhost 选项改为 Enabled,就可以了
其他浏览器也是类似的,大概就是改浏览器名称就可以了吧,不行就搜索一下自己的浏览器怎么打开这个选项。
edge 浏览器:
edge://flags/#allow-insecure-localhost
如果是用命令行启动浏览器,或者是程序内嵌浏览器启动的,可以使用 –allow-insecure-localhost 参数,如:
$ chromium-browser --allow-insecure-localhost