如何在Karate中通过Cognito与AWS_IAM认证并测试AppSync API?
可行方案:用JavaScript库拦截请求并添加AWS SigV4授权头
完全可以通过JavaScript库拦截HTTP请求,自动生成并添加AWS Signature v4所需的授权头,无需手动处理复杂的签名逻辑。以下是几种常用场景的实现方式:
1. 使用Axios拦截器(Node.js/浏览器通用)
Axios的请求拦截器可以在请求发送前自动完成签名处理,适合批量管理请求授权:
const axios = require('axios'); const { SignatureV4 } = require('@aws-sdk/signature-v4'); const { Sha256 } = require('@aws-sdk/util-hash-node'); const { defaultProvider } = require('@aws-sdk/credential-provider-node'); // 配置AppSync基础信息 const APPSYNC_ENDPOINT = 'https://your-appsync-endpoint.appsync-api.region.amazonaws.com/graphql'; const REGION = 'your-aws-region'; // 初始化SigV4签名器,自动从环境变量/本地配置获取IAM凭证 const sigv4 = new SignatureV4({ credentials: defaultProvider(), region: REGION, service: 'appsync', sha256: Sha256, }); // 创建带拦截器的Axios实例 const appsyncAxios = axios.create({ baseURL: APPSYNC_ENDPOINT }); // 添加请求拦截器,自动签名 appsyncAxios.interceptors.request.use(async (config) => { const signedRequest = await sigv4.sign({ method: config.method.toUpperCase(), hostname: new URL(APPSYNC_ENDPOINT).hostname, path: new URL(APPSYNC_ENDPOINT).pathname, headers: { 'Content-Type': 'application/json', ...config.headers, }, body: JSON.stringify(config.data), }); // 替换为签名后的请求头 config.headers = signedRequest.headers; return config; }); // 测试请求 appsyncAxios.post('', { query: 'query GetItems { items { id name } }' }) .then(res => console.log(res.data)) .catch(err => console.error(err));
2. 封装Fetch请求(原生API场景)
如果使用原生Fetch,可以封装一个签名函数,所有请求通过该函数发送:
const { SignatureV4 } = require('@aws-sdk/signature-v4'); const { Sha256 } = require('@aws-sdk/util-hash-node'); const { defaultProvider } = require('@aws-sdk/credential-provider-node'); const APPSYNC_ENDPOINT = 'https://your-appsync-endpoint.appsync-api.region.amazonaws.com/graphql'; const REGION = 'your-aws-region'; const sigv4 = new SignatureV4({ credentials: defaultProvider(), region: REGION, service: 'appsync', sha256: Sha256, }); async function signedFetch(url, options = {}) { const requestParams = { method: options.method || 'POST', hostname: new URL(url).hostname, path: new URL(url).pathname, headers: { 'Content-Type': 'application/json', ...options.headers, }, body: options.body ? JSON.stringify(options.body) : '', }; // 生成签名后的请求参数 const signedRequest = await sigv4.sign(requestParams); return fetch(url, { method: requestParams.method, headers: signedRequest.headers, body: signedRequest.body, }); } // 测试调用 signedFetch(APPSYNC_ENDPOINT, { body: { query: 'query GetItems { items { id name } }' } }) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err));
3. 浏览器端Cognito身份池场景
如果在浏览器中测试,需要通过Cognito身份池获取临时IAM凭证,替换凭证源即可:
const { CognitoIdentityClient } = require('@aws-sdk/client-cognito-identity'); const { fromCognitoIdentityPool } = require('@aws-sdk/credential-provider-cognito-identity'); const { SignatureV4 } = require('@aws-sdk/signature-v4'); const { Sha256 } = require('@aws-sdk/util-hash-node'); const REGION = 'your-aws-region'; const IDENTITY_POOL_ID = 'your-cognito-identity-pool-id'; // 格式: us-east-1:xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx // 从Cognito身份池获取临时凭证 const cognitoClient = new CognitoIdentityClient({ region: REGION }); const credentials = fromCognitoIdentityPool({ client: cognitoClient, identityPoolId: IDENTITY_POOL_ID, }); // 初始化签名器 const sigv4 = new SignatureV4({ credentials, region: REGION, service: 'appsync', sha256: Sha256, }); // 后续请求逻辑同Axios/Fetch示例
关键说明
- 凭证来源:
defaultProvider()会自动读取环境变量、AWS CLI本地配置、ECS/EC2角色等,适合后端测试;浏览器端必须用Cognito身份池获取临时凭证。 - AppSync配置:需确保你的IAM用户/角色拥有
appsync:GraphQL权限,且AppSync API的授权模式包含AWS IAM。
内容的提问来源于stack exchange,提问作者user2363392
相关产品推荐
相关产品推荐

