WebSocket 连接中使用 JWT Token 进行身份验证的正确实践
websocket 客户端需将 jwt token 通过 `authorization: bearer
在基于 WebSocket 的实时通信场景中,安全地完成用户身份鉴权至关重要。许多开发者误以为可通过 URL 查询参数(如 ?token=xxx 或 ?access_token=xxx)向 WebSocket 服务端传递 JWT,但实际中——尤其是使用 dgrijalva/jwt-go(现维护分支为 golang-jwt/jwt)等标准库进行解析时——服务端验证逻辑默认不解析查询参数中的 token。
如问题中 Go 服务端代码所示,ParseFromRequest 函数仅检查两个位置:
- Authorization 请求头(格式为 Bearer
); - access_token 表单字段(需经 req.ParseMultipartForm() 或 req.ParseForm() 解析后的 req.Form)。
而 WebSocket 握手请求(HTTP Upgrade)不会自动将 URL 查询参数注入 req.Form,即使调用了 req.ParseMultipartForm(10e6),该方法也仅处理 multipart/form-data 类型的请求体(常见于文件上传),对 application/x-www-form-urlencoded 或纯 query string 无作用。因此 req.Form.Get("access_token") 始终为空,最终返回 ErrNoTokenInRequest。
✅ 正确做法:将 Token 放入 Authorization 请求头
使用 Python 客户端(如 websocket-client)时,应通过 header 参数显式传入认证头:
from websocket import create_connection
def test_auth_token(token):
# ✅ 正确:通过 Header 传递 Bearer Token
headers = ["Authorization: Bearer " + token]
ws_url = f"ws://:port/{container.uuid}"
conn = create_connection(ws_url, header=headers)
result = conn.recv()
assert result is not None
conn.close() ⚠️ 注意事项:
- Authorization 头值必须严格遵循 Bearer
格式(注意 Bearer 后有一个空格); - 确保 Token 未被 URL 编码(若手动拼接 URL,需避免对 token 二次编码;而
header 中无需编码); - 若服务端使用较新版本 golang-jwt/jwt/v5,建议升级并配合 http.Request.Context() 进行更健壮的 token 提取与验证;
- 避免在 URL 中传递敏感 Token(易被日志、代理、浏览器历史记录泄露),Header 是更安全、符合规范的方式。
? 扩展建议:
服务端可增强兼容性,例如主动从 req.URL.Query().Get("access_token") 读取查询参数(需自行实现,非 jwt-go 默认行为)。但推荐客户端统一走 Header 方案,既符合 OAuth 2.0 / RFC 6750 规范,也便于与现有 HTTP API 鉴权逻辑保持一致。
上一篇 : 如何在 React 聊天机器人中集成 LangChain 对话记忆机制
下一篇 : 如何在 Docker 容器之间安全高效地共享和复制文件
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!
header 中无需编码);