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

React Native Expo迁移Amplify v6后uploadData上传S3遇AccessDenied错误

AWS Amplify v6 uploadData S3 AccessDenied 问题解决

我正在将基于Expo的React Native应用从AWS Amplify v5迁移至v6,使用uploadData方法向S3上传文件时遇到AccessDenied: Access Denied错误。

v5 可正常运行的代码

import * as ImageManipulator from 'expo-image-manipulator';
import { Storage } from 'aws-amplify';
import uuid from 'react-native-uuid';

export async function uploadImage(uri: string): Promise<string | null> {
  try {
    if (!uri) {
      throw new Error('Invalid URI provided for uploading the image');
    }
    const id = uuid.v4().toString();  // Generate a version 4 UUID
    const response = await fetch(uri);
    if (!response.ok && response.type !== 'default') {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob = await response.blob();
    if (!blob) {
      throw new Error('Failed to convert the response to a blob');
    }
    const result = await Storage.put(id, blob);
    if (!result.key) {
      throw new Error('Failed to upload the image');
    }
    return result.key;
  } catch (err) {
    console.error('Error uploading file: ', err);
    return null;
  }
}

v6 出现错误的代码

import { getUrl, uploadData } from 'aws-amplify/storage';
import uuid from 'react-native-uuid';

export async function uploadImage(uri: string): Promise<string | null> {
  try {
    if (!uri) {
      throw new Error('Invalid URI provided for uploading the image');
    }
    const id = uuid.v4().toString();  // Generate a version 4 UUID
    const response = await fetch(uri);
    if (!response.ok && response.type !== 'default') {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob = await response.blob();
    if (!blob) {
      throw new Error('Failed to convert the response to a blob');
    }
    console.log('id', id);
    console.log('blob', blob);
    const operation = uploadData({ path: id, data: blob })
    const result = await operation.result
    console.log('result', result);
    if (!result.path) {
      throw new Error('Failed to upload the image');
    }
    return result.path;
  } catch (err) {
    console.error('Error uploading file: ', err);
    return null;
  }
}

错误信息

Error uploading file: [AccessDenied: Access Denied]

我推测问题可能与uploadData中使用的path有关,请问应如何正确指定路径或设置访问等级以解决该错误?


解决方法

1. 显式指定访问权限等级

Amplify v5的Storage.put默认使用private访问级别,但v6的uploadData需要显式声明访问级别。修改代码,在uploadData参数中添加options.accessLevel,确保与v5的权限逻辑一致:

const operation = uploadData({
  path: id,
  data: blob,
  options: {
    accessLevel: 'private' // 根据需求选择private/public/protected
  }
})

2. 确认Path与权限规则匹配

  • 使用private级别时,Amplify会自动在path前添加private/{userId}/前缀,无需手动拼接;
  • 若你自定义了路径规则,需确保S3桶策略和IAM权限允许该路径的s3:PutObject操作。

3. 检查IAM角色权限

确保你的Cognito用户角色拥有对应路径的上传权限,示例策略如下:

{
  "Effect": "Allow",
  "Action": ["s3:PutObject"],
  "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/private/${cognito-identity.amazonaws.com:sub}/*"
}

替换YOUR_BUCKET_NAME为实际桶名,资源路径需与访问级别对应。

4. 验证Amplify配置

检查amplifyconfiguration.json中的Storage配置,确保bucket、region等参数与v5完全一致,避免配置错误导致权限验证失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:32:12