如何在CDK搭建的AppSync Lambda解析器中获取Cognito身份数据
解决方案
1. 确认客户端请求的授权模式
首先确保你客户端调用AppSync接口时,显式指定使用Cognito用户池授权,而不是默认的API_KEY。如果客户端仍使用API_KEY发起请求,自然不会携带Cognito身份信息。
2. 自定义Resolver的请求映射模板,传递身份上下文
默认的Lambda数据源请求模板只会传递查询参数,不会主动把AppSync的身份上下文传给Lambda,你需要在创建Resolver的时候显式配置映射模板:
lambdaDs.createResolver({ typeName: "Query", fieldName: "listUsers", // 自定义请求映射模板,把身份信息塞进传给Lambda的payload requestMappingTemplate: appsync.MappingTemplate.fromString(` { "version": "2017-02-28", "operation": "Invoke", "payload": { "arguments": $util.toJson($ctx.args), "identity": $util.toJson($ctx.identity), "request": $util.toJson($ctx.request) } } `), // 自定义响应映射模板,直接返回Lambda执行结果 responseMappingTemplate: appsync.MappingTemplate.fromString(` $util.toJson($ctx.result) `) });
3. 在Lambda中正确读取身份信息
注意:你要从Lambda的第一个入参event里读取identity,而不是Lambda的执行上下文context对象,这是最常见的踩坑点。以下是Node.js环境的示例代码:
exports.handler = async (event, context) => { // 从event中读取身份信息 const cognitoIdentity = event.identity; // Cognito用户池授权场景下的字段判断 if (cognitoIdentity && cognitoIdentity.sub) { console.log("当前认证用户ID:", cognitoIdentity.sub); console.log("用户所属用户池ID:", cognitoIdentity.issuer.split('/').pop()); console.log("用户所有属性声明:", cognitoIdentity.claims); } else if (cognitoIdentity?.defaultAuthProvider === 'API_KEY') { console.log("当前为未授权的API_KEY访问"); } // 原有业务逻辑,比如查询PostgreSQL等 return []; };
可选补充:Schema字段权限配置
为了确保两种授权模式都能正常访问该字段,你可以在GraphQL Schema的对应字段上添加授权指令:
type Query { listUsers: [User] @aws_api_key @aws_cognito_user_pool }
内容的提问来源于stack exchange,提问作者Andrew Pulver
相关产品推荐
相关产品推荐

