如何使用Nginx实现WebSocket请求的身份验证?
WebSocket加Basic Auth身份验证解决方案
Nginx实现方案(优先推荐)
实现逻辑
WebSocket建立连接前会发起HTTP握手请求,Nginx可以在握手阶段直接完成Basic Auth校验,非法请求直接返回401,不会透传到后端无法修改的WebSocket服务,完全满足需求。
操作步骤
- 生成密码存储文件
需要先安装apache2-utils(Debian/Ubuntu)或httpd-tools(CentOS/RHEL)包,获取htpasswd工具:
# Debian/Ubuntu安装依赖 apt install apache2-utils # CentOS/RHEL安装依赖 yum install httpd-tools # 生成密码文件,替换<username>为实际用户名,执行后按提示输入密码 htpasswd -c /etc/nginx/websocket_auth.htpasswd <username>
如果后续需要新增用户,去掉-c参数即可,避免覆盖已有密码文件。
2. 调整Nginx反向代理配置
在原有WebSocket反向代理的location块中新增Basic Auth相关配置,完整示例如下:
server { listen 80; server_name 你的WebSocket服务域名; location /ws { # 开启Basic Auth,提示文本可自定义 auth_basic "WebSocket Access Restricted"; # 关联第一步生成的密码文件路径 auth_basic_user_file /etc/nginx/websocket_auth.htpasswd; # 原有WebSocket代理配置无需修改 proxy_pass http://真实WebSocket服务地址:端口; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; # 按需调整WebSocket长连接超时时间 proxy_read_timeout 3600s; } }
- 配置生效
执行配置校验命令,确认语法无误后重载配置:
nginx -t nginx -s reload
客户端连接示例
连接时需要在请求头中携带Basic Auth凭证,JavaScript示例如下:
const username = "你的用户名"; const password = "你的密码"; const authToken = btoa(`${username}:${password}`); const ws = new WebSocket("wss://你的服务域名/ws", { headers: { Authorization: `Basic ${authToken}` } });
如果客户端不支持自定义WebSocket请求头,也可临时将凭证放在URL参数中传递,但该方式安全性较低,生产环境不推荐。
其他可选方案
如果有更多定制化校验需求,可选择以下方案:
- 轻量代理层:用Go、Python等语言开发几十行代码的反向代理中间层,在中间层完成身份校验后再转发WebSocket流量,支持对接内部账号体系、自定义校验规则等场景。
- API网关:使用APISIX、Kong等开源网关产品,自带Basic Auth、JWT等多种身份验证插件,无需开发即可配置生效,适合大规模服务集群场景。
注意事项
- 生产环境必须搭配WSS/HTTPS使用,避免Basic Auth凭证被明文传输窃取。
- 密码文件权限建议设置为
600,仅Nginx运行用户可读取,避免凭证泄露。
内容的提问来源于stack exchange,提问作者Return Cos
相关产品推荐
相关产品推荐

