31

I am following the proposed solution by Trivikr for adding support for s3.getSignedUrl api which is not currently available in newer v3. I am trying to make a signed url for getting an object from bucket.

Just for convenience, the code is being added below:

const { S3, GetObjectCommand } = require("@aws-sdk/client-s3"); // 1.0.0-gamma.2 version const { S3RequestPresigner } = require("@aws-sdk/s3-request-presigner"); // 0.1.0-preview.2 version const { createRequest } = require("@aws-sdk/util-create-request"); // 0.1.0-preview.2 version const { formatUrl } = require("@aws-sdk/util-format-url"); // 0.1.0-preview.1 //version const fetch = require("node-fetch"); (async () => { try { const region = "us-east-1"; const Bucket = `SOME_BUCKET_NAME`; const Key = `SOME_KEY_VALUE`; const credentials = { accessKeyId: ACCESS_KEY_HERE, secretAccessKey: SECRET_KEY_HERE, sessionToken: SESSION_TOKEN_HERE }; const S3Client = new S3({ region, credentials, signatureVersion: 'v4' }); console.log('1'); // for quick debugging const signer = new S3RequestPresigner({ ...S3Client.config }); console.log('2') const request = await createRequest( S3Client, new GetObjectCommand({ Key, Bucket }) ); console.log('3'); let signedUrl = formatUrl(await signer.presign(request)); console.log(signedUrl); let response = await fetch(signedUrl); console.log("Response", response); }catch(e) { console.error(e); } 

I successfully create S3Client and signer but on creating request, I get the following error:

clientStack.concat(...).filter is not a function

Anything wrong I am doing?

Please also note that I am using webpack for bundling

3 Answers 3

67

Just add my example in TypeScript:

import { S3Client, GetObjectCommand, S3ClientConfig } from '@aws-sdk/client-s3'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; const s3Configuration: S3ClientConfig = { credentials: { accessKeyId: '<ACCESS_KEY_ID>', secretAccessKey: '<SECRET_ACCESS_KEY>' }, region: '<REGION>', }; const s3 = new S3Client(s3Configuration); const command = new GetObjectCommand({Bucket: '<BUCKET>', Key: '<KEY>' }); const url = await getSignedUrl(s3, command, { expiresIn: 15 * 60 }); // expires in seconds console.log('Presigned URL: ', url); 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks very much, Tri. Where the heck is this documented?
It's a new modular aws-sdk officially released few days back. During my time of writing this question, it was in testing phase. You can view info on github page
Much obliged, @Waleed93. For others here is a link to the documentation.
Thanks, I could not find in their docs what were the params for GetObjectCommand
0

Here's my function for this. It has a bit more meat on the bone than the online documentation. It's all compatible with esbuild for tree shaking and minying the code. Some of my lambda functions that use this actually pack down into less than 10kB in size, by leveraging all the bundling and minifying options.

import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; let s3Client; // Singleton Initiation function singletonS3Client() { if (!s3Client) { s3Client = new S3Client({}); } return s3Client; } /** * Generate a presigned URL for S3 operations (upload/download) * @param {string} bucketName - S3 bucket name * @param {string} key - Object key in S3 * @param {number} expiry - Expiration time in seconds * @param {string} method - 'getObject' for download, 'putObject' for upload * @param {string} contentType - Optional MIME type (e.g., 'image/jpeg', 'image/png') * @returns {Promise<string>} - Presigned URL */ async function presignedUrl(bucketName, key, expiry = 3600, method = 'getObject', contentType = null) { // Check Method const validMethods= ['getObject', 'putObject']; if (!validMethods.includes(method)) { throw {errCode: 400, errMsg: "Invalid Method. Use 'getObject' or 'putObject'."}; } // Build params object const s3Params = { Bucket: bucketName, Key: key }; // Add content type for image uploads if provided if (method === 'putObject' && contentType) { s3Params.ContentType = contentType; } console.log('Generating presigned URL with params:', s3Params); // Initialise client s3Client = singletonS3Client(); // Generate presigned url try { let command; if (method === 'getObject') { command = new GetObjectCommand(s3Params); } else { command = new PutObjectCommand(s3Params); } const url = await getSignedUrl(s3Client, command, { expiresIn: expiry }); return url; } catch(err) { console.log('error:', err); throw new Error("Failed to generate secure url."); } } 

Comments

-7

RESOLVED

I ended up successfully making the signed urls by installing the beta versions rather than preview (default) ones

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.