简体   繁体   English

无需访问密钥的 AWS S3 JavaScript 浏览器上传

[英]AWS S3 JavaScript browser upload without access key

I want to upload a file to S3, preferably not through a backend server, but only through browser.我想将文件上传到 S3,最好不要通过后端服务器,而只能通过浏览器。

In AWS example, to create an S3 client, I need to provide secret key and secret id:在 AWS 示例中,要创建 S3 客户端,我需要提供密钥和密钥 ID:

const S3 = new AWS.S3({
    accessKeyId: <ACCESS_KEY_ID>,
    secretAccessKey: <ACCESS_KEY_SECRET>,
    region: <AWS_REGION>
});

But I don't want to expose my access keys.但我不想公开我的访问密钥。 The website is hosted in CloudFront, is it possible to setup permission between the CloudFront and S3 bucket so that I don't need to provide credentials in JavaScript?该网站托管在 CloudFront 中,是否可以在 CloudFront 和 S3 存储桶之间设置权限,以便我不需要在 JavaScript 中提供凭据?

For security reasons you should generally have some way to audit the source of an object upload to S3 (it could afterall be anything if you're allowing public access).出于安全原因,您通常应该有一些方法来审核上传到 S3 的对象的来源(如果您允许公共访问,它毕竟可以是任何东西)。

Rather than allowing completely public access it might be better to setup AWS Cognito and use it on your frontend.与其允许完全公开访问,不如设置AWS Cognito并在您的前端使用它。

You'd have the choice for one of the below scenarios:您可以选择以下场景之一:

  • User signs in via a cognito user用户通过 cognito 用户登录
  • The anonymous user is used.使用匿名用户。

Both of these options will generate temporary credentials that can be used by your frontend.这两个选项都将生成您的前端可以使用的临时凭证。 This will prevent a user making a note of them and keeping them forever, ensure you lockdown the permissions to be a putObject only for that specific S3 bucket.这将防止用户记下它们并永远保留它们,确保您锁定权限,使其仅成为该特定 S3 存储桶的 putObject。

An alternative approach is to use API Gateway and Lambda to generate a presigned URL that can support uploads.另一种方法是使用 API Gateway 和 Lambda 生成可以支持上传的预签名 URL。 For more information on this approach take a look at this article .有关此方法的更多信息,请查看本文

To enhance your security it is probably worth adding an S3 event to trigger a Lambda that will validate the object after it has been uploaded.为了增强您的安全性,可能值得添加一个S3 事件来触发一个 Lambda,该 Lambda 将在对象上传后对其进行验证。

You need some kind of backend in order to hide your credentials effectively.您需要某种后端才能有效地隐藏您的凭据。 Since you're already in the AWS universe, you could use an AWS Lambda function that returns a so-called pre-signed upload url to your frontend which you can use to upload your binaries.由于您已经在 AWS 世界中,您可以使用 AWS Lambda 函数将所谓的预签名上传 url 返回到您的前端,您可以使用它来上传二进制文件。

More info: AWS S3 Presigned URLs更多信息: AWS S3 预签名 URL

You need to use S3 presigned URLs.您需要使用 S3 预签名 URL。 Your backend generates a special URL that contains a signature and send it to the browser.您的后端会生成一个包含签名的特殊 URL 并将其发送到浏览器。 Then the browser can use that URL to send a POST request (or a PUT request, but that is a signed PUT URL) to upload the file directly to the S3 bucket.然后浏览器可以使用该 URL 发送 POST 请求(或 PUT 请求,但这是一个签名的 PUT URL)以将文件直接上传到 S3 存储桶。 No access keys are exposed to the client.没有访问密钥暴露给客户端。

You still need to add access keys to your backend, which can be through roles if it is inside AWS.您仍然需要向后端添加访问密钥,如果它在 AWS 内部,则可以通过角色添加访问密钥。 But these keys don't reach the browser, only the signature.但是这些密钥不会到达浏览器,只会到达签名。

I've written about this topic extensively and also made code examples you can check.我已经写了很多关于这个主题的文章,还制作了一些代码示例,您可以查看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM