简体   繁体   English

无法将文件上传到私有 aws S3 存储桶

[英]Can`t upload files to a private aws S3 bucket

I am trying to upload a file to aws S3 with a nodeJS server and React client app.我正在尝试使用 nodeJS 服务器和 React 客户端应用程序将文件上传到 aws S3。 I am new to aws so I guess I am doing something wrong.我是 aws 的新手,所以我想我做错了什么。 I have created a completely private backet so that only the app can access the files.我创建了一个完全私有的后台,以便只有应用程序可以访问文件。 The problem is that when I want to upload a file I need to get the link myBucket.getSignedUrl () in order to upload it.问题是,当我想上传文件时,我需要获取链接 myBucket.getSignedUrl () 才能上传它。 When I do it and send it to the frontend, the frontend fetches the link to S3 with the file I want to upload, the problem is that it returns the following error:当我这样做并将其发送到前端时,前端使用我要上传的文件获取到 S3 的链接,问题是它返回以下错误:

Access to fetch at 'https://atlasworld-progress.s3.amazonaws.com/IMG_20210202_100322.jpg?AWSAccessKeyId=AKIAZGHWWSFL5XOWPRXJ&Content-Type=image%2Fjpeg&Expires=1633937718&Signature=o8S8MQQ3fVdONePGOT4a5ic7CcU%3D' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.访问在“https://atlasworld-progress.s3.amazonaws.com/IMG_20210202_100322.jpg?AWSAccessKeyId=AKIAZGHWWSFL5XOWPRXJ&Content-Type=image%2Fjpeg&Expires=1633937718&Signature=o8S8MQQ3fVdONePGOT4a5ic7CcU%3D”从产地获取的“http://本地主机:3000”已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。 If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

Here is the aws configuration file:这是aws配置文件:

import AWS from 'aws-sdk'

AWS.config.update({
    accessKeyId: process.env.AWS_ACCESS_KEY,
    secretAccessKey: process.env.AWS_SECRET_KEY
})

const S3_BUCKET ='atlasworld-progress';
const REGION =process.env.AWS_REGION;
const URL_EXPIRATION_TIME = 60; // in seconds

const myBucket = new AWS.S3({
    params: { Bucket: S3_BUCKET},
    region: REGION,
})

export const generatePreSignedPutUrl = async (fileName, fileType) => {
    const url = await myBucket.getSignedUrl('putObject', {
        Key: fileName,
        ContentType: fileType,
        Expires: URL_EXPIRATION_TIME
    });
   return url;
}

In the express controller it simply returns to the client the link generated by the function generatePreSignedPutUrl().在 express 控制器中,它只是将函数 generatePreSignedPutUrl() 生成的链接返回给客户端。 Here is the code for the frontend function in React:这是 React 中前端函数的代码:

const [frontPhoto, setFrontPhoto] = useState();
const upload = async (e) => {
    e.preventDefault();
    await JWT.checkJWT();

    const requestObject = {
        fileName: frontPhoto.name,
        fileType: frontPhoto.type,
        token: JWT.getToken()
    };

    axiosReq.post(`${serverPath}/prepare_s3`, requestObject).then((res) => {
    //the following fetch is the one that fails
      fetch(res.data, {
        method: "PUT",
        body: frontPhoto,
      }).then((res) => {
        console.log(res);
      });
    });
}

If anyone knows what is happening I would appreciate your help.如果有人知道发生了什么,我将不胜感激。

I would also like to ask if S3 can only be uploaded one files at a time or different files can be uploaded in a single fetch.我还想问一下,S3 是一次只能上传一个文件还是可以一次上传不同的文件。

Thanks!谢谢!

I think this tells it all:我认为这说明了一切:

Access to fetch from origin 'http://localhost:3000' has been blocked by CORS policy从源“http://localhost:3000”获取的访问已被 CORS 策略阻止

you need to familiarize self with CORS .您需要熟悉CORS If you want this to work, then you need to enable CORS from AWS .如果您希望它起作用,那么您需要从 AWS 启用 CORS

It's a nginx config problem, you must increase your client_max_body_size in nginx.conf这是一个 nginx 配置问题,你必须在 nginx.conf 中增加你的client_max_body_size

Steps:脚步:

  1. Connect to your Beanstalk/EC2 instance via ssh:通过 ssh 连接到您的 Beanstalk/EC2 实例:

    ssh -i <key.pem> <ec2-user>@<host>

  2. Log in as super user:以超级用户身份登录:

    $ sudo su

  3. Edit nginx.conf编辑 nginx.conf

    nano /etc/nginx/nginx.conf

  4. Add this line inside http block在 http 块中添加这一行

    client_max_body_size 50M;

  5. Save file保存存档

  6. Restart nginx service重启nginx服务

    $ service nginx restart

EXAMPLE NGINX CONF FILE示例 NGINX 配置文件

# Elastic Beanstalk Nginx Configuration File

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log;

pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {

    client_max_body_size 50M;           --------- add this line
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log    /var/log/nginx/access.log;

    log_format  healthd '$msec"$uri"$status"$request_time"$upstream_response_time"$http_x_forwarded_for';

    include       /etc/nginx/conf.d/*.conf;
    include       /etc/nginx/sites-enabled/*;
}

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

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