You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Amplify Flutter中已通过Cognito登录仍无法访问S3对象如何解决

问题根因
  • 生成的S3访问URL未携带鉴权签名:你当前代码生成的是S3原生静态URL,浏览器直接访问时属于匿名请求,非公开对象默认会被S3拒绝,这是最常见的原因。
  • Cognito认证角色缺少S3访问权限:登录用户关联的IAM角色未配置对应S3桶的s3:GetObject权限,即使请求带签名也会被拦截。
  • 上传与获取URL时的访问级别不匹配:Amplify Storage支持private/protected/public三种访问级别,上传和读取时指定的级别不一致会导致鉴权失败。
  • S3桶策略存在额外限制:桶配置了拦截Cognito身份访问的规则,覆盖了IAM角色的权限配置。
解决方案
  • 调整getUrl方法生成带签名的预签名URL
    调用Amplify.Storage.getUrl时显式配置参数,生成带鉴权签名的有时效性URL,无需将对象设为公开即可访问,修改后的代码如下:
Future<String> getUrlS3(String UploadKey) async {
    try {
      GetUrlResult result = await Amplify.Storage.getUrl(
        key: UploadKey,
        options: GetUrlOptions(
          // 自定义签名URL有效期,最长可设为7天
          expiresIn: Duration(minutes: 30),
          // 和上传时的访问级别保持一致,未特殊指定的话默认是private
          accessLevel: StorageAccessLevel.private
        )
      );
      return result.url.toString();
    } on StorageException catch (e) {
      return e.message;
    }
}
  • 配置Cognito认证角色的S3访问权限
    在AWS IAM控制台找到你Cognito用户池关联的认证用户IAM角色,为该角色添加如下权限策略,替换其中的S3桶名为你实际使用的桶名:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::你的S3桶名/*"
        }
    ]
}
  • 匹配访问级别
    确认上传对象时指定的accessLevel参数和获取URL时的参数一致:public级别允许匿名访问,protected允许所有认证用户访问,private仅允许上传者本人访问。
  • 检查S3桶策略
    确认桶策略没有限制Cognito身份的访问,不要设置仅允许特定IAM用户访问、强制匿名访问的规则。

内容的提问来源于stack exchange,提问作者Vikram Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 02:27:00