API For Pre-signed URLs

Pre-signed URL’s are used for downloading objects from AWS S3 buckets. I’ve used them many times in the past for various reasons but this idea was a new one. A proof of concept for an API that would create the pre-signed URL and return it to the user.

This solution utilizes an API Gateway and an AWS Lambda function. The API Gateway takes two parameters “key” and “expiration”. Ultimately, you could add another parameter for “bucket” if you wanted the gateway to be able to get objects from multiple buckets.

I used Terraform to create the infrastructure and Python to program the Lambda.

Take a look at the Lambda code below:

import boto3
import json
import os
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    # Get the query parameters
    query_params = event.get('queryStringParameters', {})
    if not query_params or 'key' not in query_params:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Missing required parameter: key'})
        }
    
    object_key = query_params['key']
    expiration = int(query_params.get('expiration', 3600))  # Default 1 hour
    
    # Initialize S3 client
    s3_client = boto3.client('s3')
    bucket_name = os.environ['BUCKET_NAME']
    
    try:
        # Generate presigned URL
        url = s3_client.generate_presigned_url(
            'get_object',
            Params={
                'Bucket': bucket_name,
                'Key': object_key
            },
            ExpiresIn=expiration
        )
        
        return {
            'statusCode': 200,
            'headers': {
                'Access-Control-Allow-Origin': '*',
                'Content-Type': 'application/json'
            },
            'body': json.dumps({
                'url': url,
                'expires_in': expiration
            })
        }
        
    except ClientError as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

The Terraform will also output a Postman collection JSON file so that you can immediately import it for testing. If this code and pattern is useful for you check it out on my GitHub below.

Github


Posted

in

, ,

by

Comments

Leave a Reply