
websocket 客户端需将 jwt token 通过 `authorization: bearer
在 WebSocket 协议中,连接建立阶段本质上是 HTTP Upgrade 请求(即 GET 请求携带 Upgrade: websocket 头),因此客户端可且应当像普通 HTTP 请求一样,在请求头中携带认证信息。而你当前的实现——将 token 拼入 URL 查询参数(如 ?token=xxx 或 ?access_token=xxx)——虽语法合法,但无法被 jwt-go 的 ParseFromRequest 函数识别,原因如下:
? 为什么查询参数不生效?
ParseFromRequest 的源码逻辑明确只检查两个位置:
- Authorization 请求头(格式为 Bearer
); - 已解析的表单数据(req.Form.Get("access_token")),这要求请求是 multipart/form-data 或 application/x-www-form-urlencoded 类型,并完成 req.ParseMultipartForm() 或 req.ParseForm()。
⚠️ 关键点:WebSocket 握手请求是纯 HTTP GET,不包含请求体,也不触发自动表单解析。即使你在 URL 中添加 ?access_token=xxx,req.Form 默认为空(除非显式调用 req.ParseForm()),且 ParseFromRequest 并未尝试从 req.URL.Query() 中提取参数。
✅ 正确做法:通过请求头传递 Token
使用支持自定义 header 的 WebSocket 客户端库(如 websocket-client),在握手请求中注入 Authorization 头:
萌次元商城是一个针对二次元的开源发卡系统。系统免费开源、界面美观、功能丰富。 (存在与第三方服务器连接的付费增值服务,但自身免费功能能够满足基本需求) 版权:遵循MIT协议从lizhipay处获得授权进行再分发 特色功能: 1.可以分发密钥,作为发卡网使用 2.可以关联快递单号,作为微商自建电商平台使用 3.支持多种支付方式,包括微信、支付宝、银联和国际
from websocket import create_connection
def test_auth_token(token, ip, port, uuid):
url = f"ws://{ip}:{port}/{uuid}"
headers = [f"Authorization: Bearer {token}"] # ✅ 关键:Bearer + 空格 + token
conn = create_connection(url, header=headers)
try:
result = conn.recv()
print("Connected and received:", result)
assert result is not None
finally:
conn.close()? 注意:header 参数接受字符串列表,每项为 "Key: Value" 格式;Authorization 头值必须严格为 Bearer (注意大小写与空格)。
?️ 服务端补充建议(Go)
确保你的 Go WebSocket 服务在 Upgrade 前对原始 HTTP 请求进行 token 验证。例如(使用 gorilla/websocket):
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
// 在 Upgrade 前验证 token
token, err := jwt.ParseFromRequest(r, func(token *jwt.Token) (interface{}, error) {
return []byte("your-secret-key"), nil // 实际应使用公钥或安全密钥管理
})
if err != nil || !token.Valid {
return false
}
// 可选:将用户信息存入 context 或 session
return true
},
}若需更灵活的 token 提取(如支持查询参数),可自行封装解析逻辑,但不推荐——因查询参数易被日志、代理、CDN 缓存泄露,存在安全风险;Header 是标准、安全且符合 JWT 最佳实践的方式。
✅ 总结
- ❌ 错误:ws://host/path?access_token=xxx → ParseFromRequest 忽略 URL 查询。
- ✅ 正确:create_connection(url, header=["Authorization: Bearer xxx"]) → Header 被 ParseFromRequest 优先识别。
- ? 安全提示:永远避免在 URL 中传递敏感凭证;JWT 应始终通过 Authorization 头传输。
- ? 调试技巧:在 Go 服务端打印 req.Header 和 req.URL.Query(),确认 token 实际到达位置。








