barn4k
March 25, 2024, 3:36pm
1
The idea is:
Add an option to generate presigned URL for AWS S3 File Operation
My use case:
Need to share the s3 file with someone.
I think it would be beneficial to add this because:
it’s quite a useful option when there is a need to share some files located on the S3 with somebody (I use that method quite a lot to share a 1-day expiration link with users).
Any resources to support this?
Reference: https://community.n8n.io/t/why-am-i-not-able-to-upload-files-to-aws-s3
i try this on Code node but it’s not working:
const crypto = require('crypto');
const accessKeyId = 'YOUR_ACCESS_KEY_ID';
const secretAccessKey = 'YOUR_SECRET_ACCESS_KEY';
const region = 'YOUR_AWS_REGION';
const bucketName = 'YOUR_BUCKET_NAME';
const expiration = 60 * 60;
let outputs = [];
for (const item of $input.all()) {
const objectKey = item.json. YOUR_OBJECT_KEY;
const date = new Date();
const amzDate = date.toISOString().replace(/[:-]|\.\d{3}/g, '') + 'Z';
const dateStamp = date.toISOString().slice(0, 10).replace(/-/g, '');
const canonicalUri = '/' + objectKey;
const host = `${bucketName}.s3.${region}.amazonaws.com`;
const canonicalQuerystring = `X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=${encodeURIComponent(accessKeyId + '/' + dateStamp + '/' + region + '/s3/aws4_request')}&X-Amz-Date=${amzDate}&X-Amz-Expires=${expiration}&X-Amz-SignedHeaders=host`;
const canonicalHeaders = `host:${host}\n`;
const signedHeaders = 'host';
const payloadHash = crypto.createHash('sha256').update('', 'utf8').digest('hex');
const canonicalRequest = `GET\n${canonicalUri}\n${canonicalQuerystring}\n${canonicalHeaders}\n${signedHeaders}\n${payloadHash}`;
const algorithm = 'AWS4-HMAC-SHA256';
const credentialScope = `${dateStamp}/${region}/s3/aws4_request`;
const stringToSign = `${algorithm}\n${amzDate}\n${credentialScope}\n${crypto.createHash('sha256').update(canonicalRequest, 'utf8').digest('hex')}`;
const getSignatureKey = (key, dateStamp, regionName, serviceName) => {
const kDate = crypto.createHmac('sha256', 'AWS4' + key).update(dateStamp).digest();
const kRegion = crypto.createHmac('sha256', kDate).update(regionName).digest();
const kService = crypto.createHmac('sha256', kRegion).update(serviceName).digest();
const kSigning = crypto.createHmac('sha256', kService).update('aws4_request').digest();
return kSigning;
};
const signingKey = getSignatureKey(secretAccessKey, dateStamp, region, 's3');
const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');
const signedUrl = `https://${host}${canonicalUri}?${canonicalQuerystring}&X-Amz-Signature=${signature}`;
const output = {
json: {
signedUrl: signedUrl,
id_request: item.json.id_request,
file_path: item.json.file_path,
}};
outputs.push(output);
}
return outputs;
1 Like
I’m having the same issue.
Nice implementation with crypto library but where did you find the docs about the signature implementation?