How to use preSignedUrl with putObejct to upload files to bucket?

0

Hello, this is my first time ever on this forum. However, this is not my first time using the Amazon services such as the S3.

This time I have come here because I found myself struggling with a piece code that should have been fixed in less than 15mins but there's not success yet.

I'm using the getSignedUrl method to create a preSignedUrl:

const aws = require('aws-sdk');
const ErrorResponse = require('../utils/ErrorResponse');
const asyncHandler = require('../utils/async');
const Media = require('../models/Media');

const s3 = new aws.S3({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID_HEROKU,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY_HEROKU,
  region: process.env.AWS_BUCKET_REGION_HEROKU,
  // apiVersion: '2012-10-17',
  signatureVersion: 'v4'
});


// @desc    Get preSignedURL from Amazon AWS S3
// @route   GET /api/v1/uploads/uploadObject
// @access  Private
// @status  DONE
exports.uploadObject = asyncHandler(async (req, res, next) => {
  
  const { originalName, type, userId, userEmail } = req.query;
  const fileExtension = type.substring(type.indexOf('/') + 1);
  const key = `${originalName
    .replace(/[^a-zA-Z0-9 ]/g, '')
    .toLowerCase()}-${userId}-${userEmail
    .toLowerCase()
    .replace(/[^a-z0-9]/g, '-')}-${Date.now().toString()}.${fileExtension}`;
  
  const params = {
    Bucket: process.env.AWS_BUCKET_NAME_HEROKU,
    Key: key,
    ContentType: type,
    Expires: 5000,
    ACL: 'public-read'
  };
  
  s3.getSignedUrl('putObject', params, (err, signedURL) => {
    if (err) {
      return next(
        new ErrorResponse(
          `There was an error with the files being uploaded`,
          500
        )
      );
    }
    
    res.status(201).json({
      success: true,
      data: {
        postURL: signedURL,
        getURL: signedURL.split(`?`)[0]
      }
    });
  });
});

The code itself I believe it works great because as far as I'm concerned it creates the preSignedUrl, the problem comes when I try to access to that URL, it then takes me to a page that displays an error of NoSuchKey. I'm running out of idea. Do any of you knows what it is that might be happening?

NOTE: My bucket is public to everyone.

profile picture
asked 3 months ago31 views
1 Answer
0

Hi - Hoping that the values of "key" and attributes of object "params" are correctly resolved before being used in

s3.getSignedUrl('putObject', params, (err, signedURL) => 

Also hoping that you are using PUT method in testing tools like postman and select test file in the form-data section as an example and not using this as a GET method.

Optionally, is it possible to use and try v3 of the AWS SDK for Javascript? In v2, the S3 client can be created using single monolithic package. In v3, the service clients are prefixed with client- followed by service name. So you can create the modular S3 client by importing @aws-sdk/client-s3

Refer Generating a presigned URL to upload an object, check JavaScript SDK under "Using the AWS SDKs" : https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html

GitHub : https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/s3#code-examples

profile picture
EXPERT
answered 3 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions