如何用Socket.IO拒绝非SSL(非wss)的WebSocket连接?
拒绝未加密WebSocket连接,仅允许WSS连接的实现方案
针对你在cPanel部署的Express+Socket.IO服务器,要拒绝ws协议连接、只处理wss请求,可通过以下两种方案实现:
方案一:Socket.IO代码层面验证
由于cPanel通过反向代理(Apache/Nginx)处理SSL后转发请求到Node服务,原始请求的协议信息会通过X-Forwarded-Proto请求头传递。你可以在Socket.IO的连接事件中判断该头,拒绝非HTTPS的连接:
修改服务器代码中的连接处理逻辑:
import express from 'express'; import { createServer } from 'node:http'; import { Server } from 'socket.io'; import { join } from 'node:path'; // 补充导入join方法 const app = express(); const httpServer = createServer(app); const io = new Server(httpServer); app.get('/', (req, res) => { res.sendFile(join(__dirname, 'index.html')); }); let i = 0; io.on('connection', (socket) => { // 通过代理头判断原始请求是否为HTTPS const isSecure = socket.request.headers['x-forwarded-proto'] === 'https'; if (!isSecure) { // 直接断开非SSL连接 socket.disconnect(true); return; } socket.on('chat message', (msg) => { socket.emit('chat message', ++i + ' ' + msg); }); }); httpServer.listen(3000, () => { console.log('server running'); // 替换未定义的logger为console.log,或确保logger已导入 });
方案二:cPanel服务器配置层面拦截(更彻底)
通过web服务器(Apache/Nginx)的配置直接拦截非SSL的WebSocket请求,无需修改Node代码:
Apache环境(.htaccess配置)
在项目根目录的.htaccess文件中添加以下规则:
RewriteEngine On # 拦截所有HTTP协议的WebSocket请求,返回403禁止访问 RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteCond %{HTTPS} off RewriteRule ^ - [F,L]
或者选择强制将ws请求重定向到wss:
RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ wss://%{HTTP_HOST}$1 [L,R=301]
Nginx环境(cPanel Nginx配置)
在对应站点的Nginx配置中添加:
location /socket.io/ { # 拒绝HTTP协议的WebSocket请求 if ($scheme = http) { return 403; } # 转发请求到Node服务 proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; }
注意事项
- 确保cPanel的反向代理配置已正确传递
X-Forwarded-Proto请求头,否则代码层面的判断会失效; - 配置层面的拦截效率更高,适合生产环境优先使用。
内容的提问来源于stack exchange,提问作者Alphonsio
相关产品推荐
相关产品推荐

