JAVASCRIPT

Securely Uploading Files to AWS S3 from a Node.js Backend

Learn to implement server-side file uploads directly to AWS S3 from a Node.js application, handling security, unique naming, and temporary access URLs.

// Install: npm install express multer @aws-sdk/client-s3 @aws-sdk/s3-request-presigner uuid
const express = require('express');
const multer = require('multer');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const { v4: uuidv4 } = require('uuid'); // For unique file names

const app = express();
const upload = multer({ storage: multer.memoryStorage() }); // Store file in memory temporarily

// AWS S3 Configuration
const s3Client = new S3Client({
  region: 'us-east-1', // Replace with your S3 bucket region
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID, // Use environment variables for security
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
});
const S3_BUCKET_NAME = 'your-unique-s3-bucket-name'; // Replace with your bucket name

app.post('/upload', upload.single('file'), async (req, res) => {
  if (!req.file) {
    return res.status(400).send('No file uploaded.');
  }

  const file = req.file;
  const originalFileName = file.originalname;
  const fileExtension = originalFileName.split('.').pop();
  const s3FileName = `${uuidv4()}.${fileExtension}`; // Generate a unique file name

  const uploadParams = {
    Bucket: S3_BUCKET_NAME,
    Key: `uploads/${s3FileName}`, // Path within the bucket
    Body: file.buffer,
    ContentType: file.mimetype,
    ACL: 'private', // Access Control List: private is generally recommended
  };

  try {
    const command = new PutObjectCommand(uploadParams);
    await s3Client.send(command);

    // Optionally, generate a pre-signed URL for temporary access (e.g., for download)
    const getCommand = new PutObjectCommand({
      Bucket: S3_BUCKET_NAME,
      Key: uploadParams.Key,
    });
    const url = await getSignedUrl(s3Client, getCommand, { expiresIn: 3600 }); // URL valid for 1 hour

    res.status(200).json({
      message: 'File uploaded successfully to S3',
      s3Key: uploadParams.Key,
      fileUrl: url, // Temporary URL for demonstration
    });
  } catch (error) {
    console.error('Error uploading file to S3:', error);
    res.status(500).send('Failed to upload file to S3.');
  }
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});
How it works: This Node.js snippet shows how to handle file uploads to AWS S3 using Express.js and the AWS SDK. It uses `multer` to process incoming file data, storing it in memory. The `S3Client` is then configured with AWS credentials (securely sourced from environment variables). The file buffer is sent to S3 using a `PutObjectCommand` with a unique key and `ACL: 'private'`. Optionally, it generates a temporary pre-signed URL for clients to access the uploaded file, demonstrating a common pattern for secure file handling in cloud storage integrations.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs