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
相关产品推荐
相关产品推荐

