iOS端用Cognito用户池时,AWS AppSync无法自动上传S3Object至存储桶
嘿,看你已经把Cognito+AppSync+DynamoDB的认证写入链路搭起来了,我来帮你把相关的配置细节和注意事项梳理清楚,方便你后续维护或者排查问题:
一、先确认认证链路的核心配置
- 先检查AppSync的认证设置:在控制台的设置→认证里,得把你的Cognito用户池设为默认认证方式,并且要开启“允许已验证用户访问”的权限,不然已登录用户也没法调用变更操作。
- 客户端登录逻辑别踩坑:应用里用Cognito登录拿到ID Token后,一定要把这个Token放到AppSync请求的
Authorization头里,AppSync全靠这个识别用户身份呢。
二、S3Object JSON字符串存储的小细节
你提到的S3信息存成转义后的JSON字符串,比如:
"pdf": "{\"s3\":{\"key\":\"6_A_2018-04-26_etc.pdf\",\"bucket\":\"#####\",\"region\":\"us-west-2\"}}"
这里有两个要注意的点:
- 客户端上传完S3后,得把S3的key、bucket、region正确序列化成转义后的字符串,别直接把原始JSON传进去,不然存到DynamoDB里格式会乱,后续读取解析容易报错。
- 读取的时候记得反序列化:比如前端用
JSON.parse(),后端用Jackson或者Gson这类工具,把字符串转成对象来用。
三、AppSync PutItem请求映射模板的优化建议
你给出的模板开头是{ "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { ...,这里给你补充几个实用的优化点:
- 绑定当前登录用户:要是想让每个写入的条目都和用户绑定,防止越权写入,模板里可以加入用户身份字段,比如:
这样每个条目都能关联到当前登录的用户ID,后续做权限控制也方便。{ "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S": "${context.arguments.id}" } }, "attributeValues" : { "userId": { "S": "${context.identity.username}" }, "pdf": { "S": "${context.arguments.pdf}" }, // 其他业务字段按需添加 } } - 提前校验格式合法性:怕客户端传过来的S3 JSON字符串格式不对?可以用VTL语法加个校验,在模板开头加上:
这样能在请求到DynamoDB之前就拦截非法请求,减少无效操作。#if(!$util.isJson($context.arguments.pdf)) $util.error("Invalid S3 object JSON string - please pass a valid escaped JSON string") #end - 升级模板版本:建议把模板版本换成
2018-05-29,这个版本支持更多VTL函数,比如更灵活的类型转换,后续扩展功能更方便。
四、权限配置的补充提醒
- 确保AppSync用的IAM角色有DynamoDB的PutItem权限:角色的信任策略要包含AppSync的服务主体,权限策略里要明确允许对目标表执行
dynamodb:PutItem操作,不然AppSync没法写数据到DynamoDB。 - 要是想做细粒度权限(比如用户只能写自己的条目),可以在DynamoDB的IAM策略里加条件判断,比如:
结合前面模板里写入{ "Effect": "Allow", "Action": "dynamodb:PutItem", "Resource": "arn:aws:dynamodb:us-west-2:你的AWS账号ID:table/你的表名", "Condition": { "ForAllValues:StringEquals": { "dynamodb:LeadingKeys": ["${aws:username}"] } } }userId的操作,就能实现用户只能操作自己的数据,安全性拉满。
内容的提问来源于stack exchange,提问作者End3r117
相关产品推荐
相关产品推荐

