Gerrit
Gerrit

Reputation: 2677

How to share objects in a S3 folder and get links to them?

I upload files to a folder in an S3 bucket via the S3 JavaScript SDK. Now I want to share all objects in that folder (maybe there are more objects later) therefore I want to get a list of all objects, create pre-signed URLs of them and deliver this list to the client. Do I need to generate a link for each object? How can I create these links with the SDK? Can the link be valid for more than 12 hours?

Upvotes: 1

Views: 92

Answers (4)

Mohammed Saad Abban
Mohammed Saad Abban

Reputation: 1

how can i retrieve cid from AWS S3 sdk Response Header When Uploading to BTFS-Compatible

this is my code :

 const s3 = new S3Client({
  endpoint: "http://127.0.0.1:6001/",
  credentials: {
    accessKeyId: "82f87bd29-9aa5-492e-b479-2afc7bb73fe6", 
    secretAccessKey: "WGicMAdP6fWE9syQi1mL4utpQI3NZwpqs"
  },
  forcePathStyle: true,
  apiVersion: "v4",
  region: "us-east-1"
});

try {
        const response = await s3.send(new PutObjectCommand(params));
        console.log(await response);
      } catch (caught) {
        if (
          caught instanceof S3ServiceException &&
          caught.name === "EntityTooLarge"
        ) {
          console.error(
            `Error from S3 while uploading object to ${bucketName}. \
    The object was too large. To upload objects larger than 5GB, use the S3 console (160GB max) \
    or the multipart upload API (5TB max).`
          );
        } else if (caught instanceof S3ServiceException) {
          console.error(
            `Error from S3 while uploading object to ${bucketName}.  ${caught.name}: ${caught.message}`
          );
        } else {
          throw caught;
        }
      }

response output

Upvotes: 0

John Rotenstein
John Rotenstein

Reputation: 269330

Rather than generating pre-signed URLs for all objects, it is recommended to create pre-signed URLs at the time that the URLs are requested. This way, a short time period can be specified on the pre-signed URL (eg 5 minutes), which enhances security.

For example, imagine a file-sharing app. Users might upload files through the app and the files are stored in S3. When the user accesses the app to see a listing of their files, the back-end should generate a pre-signed URL for each link at the time that the list is requested, with each link only valid for a short time. When the user clicks a link, they will have access to that file.

Each object will have its own URL, which includes its own signature and expiry time.

From Sharing objects with presigned URLs - Amazon Simple Storage Service:

When you use the AWS SDKs to generate a presigned URL, the maximum expiration time is 7 days from the time of creation.

Upvotes: 0

AWS PS
AWS PS

Reputation: 4710

Unfortunately, S3 does not natively support folders. Instead, it uses a flat structure where "folders" are simulated through prefixes in object keys (e.g., folder_name/). You cannot directly create a presigned URL for a "folder," but you can allow access to all files under a certain prefix (i.e., "folder") by using a bucket policy or using IAM roles with the necessary permissions.

Here’s a workaround you can consider:

  1. Generating Presigned URLs for All Files in a "Folder": You can programmatically generate presigned URLs for each object under a specific prefix (folder-like structure).

  2. Alternative: Use an S3 Bucket Policy with Prefix Restrictions: If you want to share access to all objects under a "folder" (prefix) without generating multiple presigned URLs, you could configure an S3 bucket policy to grant access to all objects with a specific prefix for a certain user or group.

Sample code in node.js https://appp.me/4yRaMH

Upvotes: -2

smac2020
smac2020

Reputation: 10704

Here is your solution

const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');

async function getURL(bucketName, keyName) {
  const s3Client = new S3Client();

  try {
    const getObjectCommand = new GetObjectCommand({
      Bucket: bucketName,
      Key: keyName,
    });

    const url = await s3Client.getSignedUrl(getObjectCommand, { expiresIn: 3600 });
    console.log(`The URL for ${keyName} is ${url}`);
  } catch (err) {
    console.error(err.message);
  }
}

In this example, we use the GetObjectCommand from the @aws-sdk/client-s3 package to generate a pre-signed URL for the specified object. The getSignedUrl method is used to generate the URL, which expires in 3600 seconds (1 hour).

Upvotes: 0

Related Questions