首页 文章

如何通过Heroku / Node.js配置简单的静态AWS S3映像(403访问错误)

提问于
浏览
0

我一直在尝试为AWS S3存储桶配置读取权限而没有运气 .

我的用例:在Node.js / express上运行的私有应用程序,它显示来自S3存储桶的静态徽标图像文件 . 存储在S3存储桶中的图像文件不应公开访问,并且仅被提取以显示在我的应用程序的视图中 . 出于这个问题的目的,我实际上是在提供包含单个图像元素的单个HTML页面 .

我已按照this Heroku guide中的步骤进行操作,这表明如果您在Heroku的配置变量中设置了有效的AWS密钥对(表示具有适当凭据的AWS角色)和S3存储桶名称,您应该只需将链接插入S3映像将文件存入您的HTML,它应该在网站上呈现 .

到目前为止,我的大部分时间都在使用S3存储桶上的AWS权限和我正在使用的IAM角色 .

这是我到目前为止所做的:

  • 在AWS上,我创建了一个名为“userx”的IAM用户,其中包含“Programmatic access”(即生成的密钥对) . 在用户创建期间,我通过“直接附加现有策略”设置权限,并将“AmazonS3FullAccess”策略附加到我的新用户 . 假设此用户的ARN为“arn:aws:iam :: 12345:user / userx”

  • 生成新用户(以及新的访问密钥ID秘密访问密钥),我通过以下方式在终端窗口中更新我的Heroku配置:

heroku config:设置AWS_ACCESS_KEY_ID = 123MYACCESSKEYID

其次是:

heroku config:set AWS_SECRET_ACCESS_KEY=123MYSECRETKEYxyz
  • 我创建一个名为'my-assets'的AWS S3存储桶,并将权限设置为"Do not grant public read access to this bucket."我将单个图像文件上传到此存储桶:myimage.png . 我通过生成新的存储桶策略并将其附加到存储桶来设置存储桶权限:
{
    "Version": "2012-10-17",
    "Id": "Policy1528038465156",
    "Statement": [
        {
            "Sid": "Stmt1528038463415",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::12345:user/userx"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-assets",
                "arn:aws:s3:::my-assets/*"
            ]
        }
      ]
    }

在heroku上,我通过以下方式设置存储桶名称:

heroku config:set S3_BUCKET_NAME=my-assets
  • 我在我的存储桶上设置了CORS配置,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

在heroku上,我重新启动我的服务器,并启动我的应用程序,该应用程序当前正在使用一个元素提供单个html文件:

<<img src="https://s3.amazonaws.com/my-assets/myimage.png" />

在我的chrome终端中,当页面加载时,对S3存储桶的请求失败,出现403 Forbidden错误 .

我的理解是 - 对于获取静态文件的简单情况 - Heroku应该处理对我的S3存储桶的GET请求,使用我加载到其配置变量中的密钥对对请求进行签名,并且该请求应该有权读取映像文件来自我的S3存储桶,因为上面给出了IAM,存储桶策略和CORS配置 .

我已经三次检查了我的密钥对等等 . 我认为不需要做任何事情来配置从heroku到AWS的请求(即我不需要使用AWS SDK或类似的东西) ?

1 回答

  • 1

    这与heroku无关,heroku不提供您的文件,您直接从浏览器访问s3 .

    如果要直接从s3提供文件,则必须为这些文件提供公共读取权限 .

    要公开文件,只需:

    click file > More > Make public

    如果要从服务器上传/读取私有存储桶中的文件,则需要访问密钥,但如果您从浏览器请求具有公共读取访问权限的S3中托管的映像,则不需要访问密钥 .

    关于您的CORS配置,您可以查看以下问题:

    Cors error while downloading image from S3


    如果要将文件保密,并且只允许某些经过身份验证的用户查看它们,则可以使用 aws-sdk 生成已签名的S3 URL,并在浏览器中使用该URL .

    const AWS = require('aws-sdk')
    
    const s3 = new AWS.S3()
    AWS.config.update({ 
        accessKeyId: 'keyId', 
        secretAccessKey: 'accessKey'
    })
    
    const params = {
        Bucket: 'bucket-name',
        Key: 'my-assets/myimage.png',
        Expires: 60 // Seconds
    };
    
    (async() => {
    
        s3.getSignedUrl('getObject', params, (err, url) => {
            console.log(url);
    
            // This is the URL that you need to use on your HTML
        });
    
    })();
    

相关问题