Websocket连接Python报Cloudfront 401 Unauthorized:成因及疑问
问题描述
在HTML+JavaScript环境中WebSocket连接完全正常,但使用Python的websockets或websocket-client库,携带相同请求头发起连接时,收到以下错误:
Handshake status 401 Unauthorized
{'content-type': 'application/json; charset=utf-8', 'content-length': '0', 'connection': 'close', 'date': 'Sun, 16 Jun 2024 22:56:20 GMT', 'x-cache': ' Error from cloudfront'}
请问该问题的成因是什么?需要停止发送哪些内容?
问题成因及解决方案
常见成因
- 浏览器自动携带的Cookie缺失:浏览器发起WebSocket请求时会自动带上当前域名下的会话认证Cookie,但Python库默认不会自动处理Cookie,这是最常见的触发401的原因。
- 请求头存在隐性差异:即便你认为请求头完全一致,实际可能有这些不同:
- 浏览器会自动添加符合当前页面域名的
Origin头,若Python手动设置的Origin不符合服务端校验规则,会被拒绝。 - 部分服务端会校验
User-Agent,Python库默认的User-Agent可能被拦截。 - 浏览器会自动处理部分WebSocket相关的隐式头(如
Sec-WebSocket-Extensions),若Python发送的内容和浏览器不一致,会触发校验失败。
- 浏览器会自动添加符合当前页面域名的
- CloudFront拦截:响应头中的
x-cache: Error from cloudfront说明请求经过CloudFront时被拦截,它可能有WAF规则或额外认证校验,比如检查请求是否来自合法浏览器环境。
需要调整/停止发送的内容
- 若手动添加了错误的
Origin头,停止发送不符合实际的Origin值,改为和浏览器完全一致的域名。 - 停止发送浏览器不会携带的自定义冗余请求头,服务端可能会校验请求头的合法性。
- 若服务端不要求某些WebSocket扩展,停止发送
Sec-WebSocket-Extensions中浏览器没有的内容,尽量和浏览器的请求头保持一致。
排查建议
- 用浏览器开发者工具(F12)抓取WebSocket握手的请求头,和Python代码中的请求头逐行对比,找出差异项。
- 在Python代码中完全复制浏览器的请求头(包括Cookie、Origin、User-Agent等)后再测试连接。
- 检查CloudFront的配置,确认是否有WAF规则拦截了非浏览器发起的请求。
内容的提问来源于stack exchange,提问作者Nathan Almeida
相关产品推荐
相关产品推荐

