放大 S3 图像 - 404 未找到

Amplify S3 Image - 404 Not Found

我正在尝试访问已上传到我的 S3 存储桶的图像。我使用 Amplify CLI (amplify add storage) 创建了我的存储桶,并授予了对我所有认知组的访问权限。我还授予了我的 AuthRole AmazonS3FullAccess。我的存储桶也设置为允许所有 public 访问。

我已经尝试了所有可以在网上找到的不同方法来访问此图像,目前唯一有效的方法是让它对 public 开放并直接使用图像 url .但是即使我使用 public 方法使用 Amplify 的工具访问图像,我也会收到 404 错误。下面是我的代码,我在 url 代做错了吗?

资源:

import React, { Component} from 'react'
import Amplify, { Auth, Storage } from 'aws-amplify';
import { AmplifyS3Image} from "@aws-amplify/ui-react";
import { Card } from 'reactstrap';

// FYI, this all matches my aws-exports and matches what I see online in the console
Amplify.configure({
    Auth: {
        identityPoolId: 'us-east-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', //REQUIRED - Amazon Cognito Identity Pool ID
        region: 'us-east-1', // REQUIRED - Amazon Cognito Region
        userPoolId: 'us-east-1_XXXXXXXXX', //OPTIONAL - Amazon Cognito User Pool ID
        userPoolWebClientId: 'XXXXXXXXXXXXXXXXX', //OPTIONAL - Amazon Cognito Web Client ID
    },
    Storage: {
        AWSS3: {
            bucket: 'xxxxxxxxx-storage123456-prod', //REQUIRED -  Amazon S3 bucket name
            region: 'us-east-1', //OPTIONAL -  Amazon service region
        }
    }
});

class TestPage extends Component {
    constructor(props) {
        super(props);
        this.state = {  }
    };

    async componentDidMount() {
        const user = await Auth.currentAuthenticatedUser();
        const deviceKey = user.signInUserSession.accessToken.payload['device_key']
        console.log( deviceKey, user );

        const storageGetPicUrl = await Storage.get('test_public.png', {
            level: 'protected',
            bucket: 'xxxxxxxxx-storage123456-prod',
            region: 'us-east-1',
          });
        console.log(storageGetPicUrl);
        
        this.setState({
            user,
            deviceKey,
            profilePicImg: <img height="40px" src={'https://xxxxxxxxx-storage123456-prod.s3.amazonaws.com/test_public.png'} />,
            profilePicPrivate: <AmplifyS3Image imgKey={"test_default.png"} />,
            profilePicPublic: <AmplifyS3Image imgKey={"test_public.png"} />,
            profilePicPrivate2: <AmplifyS3Image imgKey={"test_default.png"} level="protected" identityId={deviceKey} />,
            profilePicPublic2: <AmplifyS3Image imgKey={"test_public.png"} level="protected" identityId={deviceKey} />,
            profilePicStorage: <img src={storageGetPicUrl} />,
          });
    };

    render() { 
        return ( 
            <table>
                <tbody>
                    <tr><td><Card>{this.state.profilePicImg}</Card></td></tr>
                    <tr><td><Card>{this.state.profilePicPrivate}</Card></td></tr>
                    <tr><td><Card>{this.state.profilePicPublic}</Card></td></tr>
                    <tr><td><Card>{this.state.profilePicPrivate2}</Card></td></tr>
                    <tr><td><Card>{this.state.profilePicPublic2}</Card></td></tr>
                    <tr><td><Card>{this.state.profilePicStorage}</Card></td></tr>
                </tbody>
            </table>
        );
    };
};
 
export default TestPage;

好的,我知道了!有两个问题。第一,AWS 存储要求您以某种方式在存储桶中组织文件夹结构以供访问。第二,我必须更新我的存储桶策略以指向我的 AuthRole。

  1. 当您配置存储桶时,Amplify CLI 将为您的 S3 存储桶设置访问权限,使 'public' 文件夹中的内容可供登录您的应用程序的每个人访问。 'private' 用于用户特定的内容,'受保护' 用于用户特定的并且可以被平台中的其他用户访问。 SOURCE
  2. 存储桶策略本身需要更新,以便对您用于网页登录的 AuthRole 进行身份验证。对我来说,这是我的 Cognito 用户链接到的 AuthRole。 This link helped me set the Actions in my policy, but I think it's an old policy format. This link helped me with getting the policy right.

我的图像位于:public/test.png 在我的存储桶中。文件夹名称 'public' 必须与下面的存储调用中指定的级别相匹配。我通过设置所有权限阻止 Public 访问来对此进行测试。我 运行 我的代码没有改变我的政策,图像无法加载,所以它们肯定被阻止了。更新政策后,图片完美加载。

我代码中重要部分的简化版本:

import { Storage } from 'aws-amplify';

// image name should be relative to the public folder
// example: public/images/test.png => Storage.get('images/test.png' ...
const picUrl= await Storage.get('test.png', {
  level: 'public',
  bucket: 'bucket-name',
  region: 'us-east-1',
});
const img = <img width="40px" name="test" src={picUrl} alt="testImg" />

我的存储桶政策:

{
    "Version": "2012-10-17",
    "Id": "Policy1234",
    "Statement": [
        {
            "Sid": "AllowReadWriteObjects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::the-rest-of-my-authrole-arn"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ]
}