如何在Lambda函数中获取Cognito用户池身份信息?
我当初踩过一模一样的坑,先给你明确说:完全不需要身份池就能拿到用户的身份信息,问题出在API Gateway的配置和你找信息的位置上,下面一步步给你讲清楚:
为什么Lambda的context里没有用户信息?
API Gateway默认不会把Cognito授权器解析出的用户信息自动放到Lambda的context对象里——其实这些信息根本不在context里!如果你的API用的是Lambda代理集成,用户的身份claims(比如sub、email、username这些)会被放在Lambda的event对象里,具体路径是event.requestContext.authorizer.claims。
举个Python Lambda的例子,你可以这样获取用户ID和邮箱:
def lambda_handler(event, context): # 从event中取出Cognito解析后的用户claims user_claims = event['requestContext']['authorizer']['claims'] user_id = user_claims['sub'] user_email = user_claims['email'] return { 'statusCode': 200, 'body': f"Hello {user_email}, your user ID is {user_id}" }
如果是非代理集成怎么办?
如果你的API用的是非代理集成(手动配置请求映射),那需要你手动在API Gateway的集成请求里配置映射模板,把Cognito的claims映射到Lambda能接收的参数里:
- 进入API Gateway控制台,找到你的API和对应的POST方法
- 切换到「集成请求」标签
- 找到「映射模板」,添加一个对应请求Content-Type的模板(比如
application/json) - 在模板里写入需要映射的字段,比如:
{ "userId": "$context.authorizer.claims.sub", "userEmail": "$context.authorizer.claims.email", "username": "$context.authorizer.claims.username" }
这样Lambda就能从event的根节点直接拿到这些字段了。
关于用ID令牌查询用户池的问题
其实完全没必要这么做——Cognito授权器已经帮你验证了ID令牌的合法性,并且解析出了所有claims信息,直接用这些信息就足够了,额外调用用户池API反而会增加延迟和成本。如果确实需要调用的话,你需要给Lambda配置cognito-idp:AdminGetUser或者cognito-idp:GetUser的权限,并且用令牌里的sub或者username去查询,但这属于冗余操作。
身份池的作用是什么?
身份池(Cognito Identity Pool)主要是用来给用户生成临时的AWS服务凭证,让用户可以直接访问S3、DynamoDB等AWS资源,而不需要通过你的Lambda中转。如果你只是需要获取用户的基本身份信息(比如邮箱、用户ID),完全不需要配置身份池,上面的方法就足够解决问题。
总结步骤
- 先确认你的API Gateway是否使用了Lambda代理集成:如果是,直接从
event.requestContext.authorizer.claims获取用户信息 - 非代理集成的话,配置映射模板把需要的claims字段映射到Lambda的event中
- 不需要身份池来获取用户身份信息,身份池是用于AWS资源访问授权的场景
内容的提问来源于stack exchange,提问作者Mark Probst

