如何在AWS Cognito用户池为App Client添加自定义字段并在Lambda中使用
可行实现方案
下面是3种适配现有技术栈、无需修改client credentials flow的实现方式,按实现复杂度从低到高排序:
方案1:API Gateway授权器透传claim + 预存映射表
该方案不需要修改Cognito侧的令牌生成逻辑,完全在API Gateway和后端逻辑层实现:
- 先在Cognito用户池的App Client属性里配置自定义字段,比如
custom:org_name,填写每个应用客户端归属的组织名称 - 配置API Gateway的Cognito授权器时,添加请求上下文映射,把JWT里默认携带的
client_idclaim,映射到API Gateway的请求上下文变量$context.authorizer.client_id - 如果你使用的是HTTP API,直接在路由的集成配置里,把上下文变量作为请求头/参数透传给Lambda;如果是REST API,可以在集成请求的映射模板里添加该字段
- 可以提前把所有App Client的client_id和对应org_name的映射关系存在DynamoDB表/参数存储里,Lambda收到请求后用client_id查询即可获取组织信息;也可以直接调用Cognito的
describe_user_pool_client接口实时查询自定义属性,适合客户端数量少的场景 - 审计需求可以直接在API Gateway访问日志里开启
$context.authorizer.client_id字段的落盘,后续和映射表关联即可生成带组织名称的审计日志
优点:无需改动Cognito的令牌逻辑,不会引入额外的认证流程开销,对调用方完全透明
缺点:需要额外维护映射关系或调用Cognito接口查询,有少量额外开销
方案2:Cognito预令牌生成触发器自定义JWT字段
旧资料显示client credentials flow不支持预令牌生成触发器,目前Cognito已经支持该场景下的触发器调用:
- 为Cognito用户池配置预令牌生成(Pre Token Generation) Lambda触发器
- 触发器逻辑中,从事件参数里拿到
clientId字段,调用Cognito接口查询该App Client的custom:org_name自定义属性 - 将
org_name写入到JWT的自定义claim中,返回给Cognito后会把该字段放入最终生成的access token里 - API Gateway侧的Cognito授权器会自动解析该自定义claim,你可以直接映射该字段到请求上下文,透传给Lambda,也可以直接在访问日志里落盘该字段
- Lambda侧可以直接拿到透传的org_name,无需额外查询
优点:一次配置后续无需额外查询,组织信息直接存在令牌里,读取效率极高
缺点:需要额外开发维护预令牌触发器,令牌长度会略有增加
方案3:按组织分配自定义scope
如果你的组织数量不多,可以为每个组织分配专属的自定义OAuth scope:
- 在Cognito用户池的资源服务器中,为每个组织创建对应scope,比如
org:xxx - 为每个App Client关联对应归属组织的scope,调用方请求令牌时申请对应scope
- API Gateway侧可以直接解析令牌里的scope字段,映射到请求上下文透传给Lambda,直接区分组织归属
优点:配置简单,无需额外开发代码
缺点:仅适合组织数量少、变动不频繁的场景,灵活性较低
内容的提问来源于stack exchange,提问作者İhsan Akin
相关产品推荐
相关产品推荐

