如何通过JavaScript WebSocket向AWS API Gateway传递x-api-key请求头?
解决原生JavaScript WebSocket无法传递x-api-key请求头的问题
问题本质
浏览器原生WebSocket构造函数不支持直接设置自定义请求头,这是API本身的限制,所以直接尝试添加x-api-key头的方式走不通。而Postman能成功,是因为它的WebSocket握手逻辑允许自定义HTTP头,但浏览器环境下没有这个能力。
可行解决方案
针对AWS API Gateway的场景,有两种实用的解决方式:
1. 将API Key放入URL查询参数(最简单)
AWS API Gateway支持从查询字符串中读取API Key,只需先调整API Gateway的配置:
- 登录AWS控制台,进入目标WebSocket API的Settings页面
- 将
API Key Source改为HEADER OR QUERY_STRING - 保存后重新部署API
然后修改Vue中的代码,把x-api-key作为URL参数传递:
const apiKey = '你的API_KEY'; const wsUrl = '你的WebSocket端点URL'; const con = new WebSocket(`${wsUrl}?x-api-key=${apiKey}`);
2. 使用AWS SigV4签名连接(更安全,适合敏感场景)
如果不想把API Key直接暴露在URL中,可以用AWS SigV4对WebSocket连接请求进行签名,同时携带API Key。步骤如下:
首先安装依赖包:
npm install @aws-sdk/signature-v4 @aws-crypto/sha256-js
然后在Vue组件中实现签名逻辑:
import { SignatureV4 } from '@aws-sdk/signature-v4'; import { Sha256 } from '@aws-crypto/sha256-js'; async function createSignedWebSocket() { const region = '你的AWS区域(如us-east-1)'; const apiKey = '你的API_KEY'; const baseWsUrl = '你的WebSocket端点URL'; const urlObj = new URL(baseWsUrl); // 初始化签名工具 const sigv4 = new SignatureV4({ credentials: { accessKeyId: '你的AWS IAM Access Key', secretAccessKey: '你的AWS IAM Secret Key', }, region, service: 'execute-api', sha256: Sha256, }); // 生成带签名的请求参数 const signedRequest = await sigv4.sign({ method: 'GET', hostname: urlObj.hostname, path: urlObj.pathname, protocol: 'wss', query: { 'x-api-key': apiKey, }, }); // 拼接最终的WebSocket URL const signedUrl = `${baseWsUrl}?${new URLSearchParams(signedRequest.query).toString()}`; return new WebSocket(signedUrl); } // 在Vue中调用创建连接 // this.con = await createSignedWebSocket();
验证
修改后重新测试连接,AWS API Gateway的日志应该不会再返回403错误,连接可以正常建立。
内容的提问来源于stack exchange,提问作者Cihaan
相关产品推荐
相关产品推荐

