Search code examples
javascriptreactjsreact-dropzone

How to use react-s3-uploader with reactjs?


I am new to reactjs want to upload image on s3, But don't know how it would work... And don't know where will I get the image path come from aws (in which function)?

Here is my react code

import ApiClient from './ApiClient';  // where it comes from?

function getSignedUrl(file, callback) {
  const client = new ApiClient();
  const params = {
    objectName: file.name,
    contentType: file.type
  };

  client.get('/my/signing/server', { params })   // what's that url?
  .then(data => {
    callback(data); // what should I get in callback?
  })
  .catch(error => {
    console.error(error);
  });
}

My server file Server.js

AWS.config.setPromisesDependency(Bluebird)

AWS.config.update({
  accessKeyId: 'accessKey',
  secretAccessKey: 'secret',
  region: 'ap-south-1'
})

const s3 = new AWS.S3({
  params: {
    Bucket: 'Bucketname'
  },
  signatureVersion: 'v4'
})

class S3Service {

  static getPreSignedUrl(filename, fileType, acl = 'public-read') {
    return new Bluebird(resolve => {
      const signedUrlExpireSeconds = 30000
      return resolve({
          signedRequest : s3.getSignedUrl('putObject', {
            Key: "wehab/"+filename,
            ContentType:"multipart/form-data",
            Bucket: config.get('/aws/bucket'),
            Expires: signedUrlExpireSeconds
          }),
          url : `https://${config.get('/aws/bucket')}.s3.amezonaws.com/wehab/${filename}`
        })
    })
  }

}

Solution

  • First You need to create s3 bucket and attach these policies if bucket name is 'DROPZONEBUCKET' ( Bucket is globally unique )

    Policy

    {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Sid": "PublicReadGetObject",
               "Effect": "Allow",
               "Principal": "*",
               "Action": [
                   "s3:PutObject",
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::DROPZONEBUCKET/*"
           }
       ]
    }
    

    CORS config

    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
       <AllowedOrigin>*</AllowedOrigin>
       <AllowedMethod>GET</AllowedMethod>
       <AllowedMethod>PUT</AllowedMethod>
       <MaxAgeSeconds>9000</MaxAgeSeconds>
       <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    </CORSConfiguration>
    

    Then run your node.js server and try to upload the file.

    Once you select upload file it will call this getSignedUrl(file, callback) function and it returns url.

    Once you successfully get this URL you can upload the file.

    Then file path is https://s3.amazonaws.com/{BUCKET_NAME}/{FILE_NAME}

    ex.

    https://s3.amazonaws.com/DROPZONEBUCKET/profile.jpeg
    

    Modify API like this

    var s3Bucket = new AWS.S3();
    
    var s3 = new Router({ mergeParams: true });
    
    var params = {
        Bucket: 'BUCKET_NAME', // add your s3 bucket name here
        Key: data.filename,
        Expires: 60,
        ContentType: data.filetype
      };
    
      s3Bucket.getSignedUrl('putObject', params, function (err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     console.log(data);           // successful response
    });