AWS Amplify处理S3上传:如何用Cognito用户ID替代联合ID存储结果?
问题分析与解决方案
当前架构合理性
你的整体架构(Amplify托管+Cognito认证+S3上传触发Lambda+数据库存储)是典型的Serverless应用模式,本身是合理的,核心问题仅在于用户身份标识(Cognito用户ID sub)与S3路径中联合ID的映射环节。
推荐解决方案
方案1:修改S3上传路径,直接写入Cognito用户ID(sub)
这是最直接的解决方式,无需依赖Amplify默认的联合ID路径,手动构造包含用户sub的上传路径:
- 前端通过Amplify Auth获取当前用户的
sub:const currentUser = await Auth.currentAuthenticatedUser(); const userSub = currentUser.attributes.sub; - 构造自定义上传路径:
myPrivatePrefix/${userSub}/<文件名> - 调用Amplify Storage上传时,指定该路径覆盖默认规则:
await Storage.put(`${userSub}/filename.txt`, file, { level: 'private' // 保持私有存储级别 }); - 同步更新S3权限策略:确保用户仅能访问自身
sub路径下的文件,可在Amplify CLI的存储配置中调整资源路径规则,或自定义IAM策略限制访问范围。
方案2:上传时附加用户sub作为S3文件元数据
无需修改路径,通过文件元数据传递用户sub,安全且易实现:
- 前端上传时添加自定义元数据:
const userSub = (await Auth.currentAuthenticatedUser()).attributes.sub; await Storage.put('filename.txt', file, { metadata: { 'user-sub': userSub }, level: 'private' }); - Lambda触发时,从S3事件中读取元数据:
# Python Lambda示例 for record in event['Records']: user_sub = record['s3']['object']['userMetadata']['user-sub'] # 后续用user_sub关联数据库记录 - 优势:保留Amplify默认的S3路径规则,元数据由前端在认证后生成,结合S3私有存储权限,无法被未授权用户篡改。
对你备选方案的评价
- 存入含Cognito ID的txt文件:存在明显安全风险,用户可轻易篡改文件内容,导致身份关联错误,不推荐。
- 建立联合ID与
sub的映射库:实现成本高,需额外维护映射关系,且可能出现身份同步不一致的问题,性价比远低于上述两种方案。
关于联合ID转sub的补充说明
AWS确实提供了通过联合ID获取用户sub的API,但操作繁琐且需要额外权限:
- 可在Lambda中调用
cognito-identity:GetIdentityCredentialsForIdentity获取临时凭证,再通过cognito-idp:AdminGetUser查询用户信息,但需为Lambda配置cognito-identity:GetIdentityCredentialsForIdentity和cognito-idp:AdminGetUser权限,且流程复杂,不如直接在上传阶段传递sub高效。
内容的提问来源于stack exchange,提问作者Moritz Eich
相关产品推荐
相关产品推荐

