使用服务器端加密上传和获取 S3 存储桶的文件 URL

问题描述

我的应用程序使用 API Gateway 和无服务器框架在 AWS Lambda 上运行。其中一项功能用户可以生成一个上传到 S3 的 excel,并将其位置 URL 返回给用户(UI 前端),他可以在那里下载生成的 excel。

像这样:


//...excel is generated

const s3 = new aws.S3();
const stream = new Stream.Passthrough();

let uploadedFileName = excelFileName + "_" + Date.Now() + '.xlsx';

await workbook.xlsx.write(stream);
let uploadResponse = await s3.upload({
    Key: uploadedFileName,Bucket: process.env.awsBucket,Body: stream,ACL: 'public-read',}).promise();

return { url: uploadResponse.Location };

API 将上传文件位置作为响应发送给 UI,然后 UI 会打开链接

最近我们决定通过静态服务器端加密来收紧我们的 S3 存储桶,并在认情况下将任何插入的文档设为私有

为此在我的 serverless.yml 文件添加

resources:
    Resources:
        DocumentationBucket:
            Type: "AWS::S3::Bucket"
            Properties:
                AccessControl: Private
                BucketName: ${self:custom.awsPermaBucket}
                CorsConfiguration:
                    CorsRules:
                        - AllowedMethods:
                            - GET
                            - HEAD
                          AllowedOrigins:
                            - "*"
                BucketEncryption:
                    ServerSideEncryptionConfiguration:
                        - ServerSideEncryptionByDefault:
                            SSEAlgorithm: 'aws:kms'
                            KMSMasterKeyID: alias/aws/s3

如您所见,我没有使用客户托管密钥,而是使用了 AWS 托管密钥。现在,当我测试相同的功能时,它确实创建了 excel 文件 > 将其上传到 S3 存储桶,但是在 UI 上打开返回的 URL 时,我收到以下错误

<Error>
    <Code>InvalidArgument</Code>
    <Message>Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.</Message>
    <ArgumentName>Authorization</ArgumentName>
    <ArgumentValue>null</ArgumentValue>
    <RequestId>C99HG5ACCVRRA327</RequestId>
    <HostId>BG2IyL2WDEmA3irG9PwOTQFYeZJkpr2pzb40tgdB09JZQ3m+TspCvVJeJXbqO2k/ZUCz949FYrk=</HostId>
</Error>

所以我将代码更改为以下内容

let response = await s3.putObject({
    Bucket: process.env.awsBucket,Key: uploadedFileName,ServerSideEncryption: 'aws:kms',ACL: "private"
}).promise();

现在文件甚至没有上传到 S3,我收到以下错误

TypeError: Converting circular structure to JSON
      --> starting at object with constructor 'Passthrough'
      |     property '_writableState' -> object with constructor 'WritableState'
      |     property 'afterWriteTickInfo' -> object with constructor 'Object'
      --- property 'stream' closes the circle
      at JSON.stringify (<anonymous>)
      at Function.logGenericError (C:\Locusnine\TQMI\tqmi-organisation-goals\src\logger\logger.ts:16:45)
      at C:\Locusnine\TQMI\tqmi-organisation-goals\src\utilities\request-wrapper.ts:86:26
      at C:\Locusnine\TQMI\tqmi-organisation-goals\src\utilities\joi-request-validator.ts:26:13
      at cors (C:\Locusnine\TQMI\tqmi-organisation-goals\node_modules\@koa\cors\index.js:98:16)

我想知道如何使用 AWS KMS 使用的相同加密方案将文件上传到 S3,然后获取上传文件 URL,然后用户可以打开(下载文件

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)