swiftamazon-web-servicesamazon-s3vapor

How do I generate a presigned URL using the AWS SDK for Swift?


I'm using Vapor to build a server side Swift application and I'm using the AWS SDK for Swift for interacting with S3.

I want to create a pre-signed URL for an object so that users can download and view PDF documents.

How can I do that with the SDK? Am I right to assume that this is not available in the Swift SDK (yet)?


Solution

  • Am I right to assume that this is not available in the Swift SDK (yet)?

    No, it is available in the SDK but as the AWS SDK for Swift is still in developer preview, the docs are very sparse.

    Use the .presignURL extension on the GetObjectInput and PutObjectInput structs to generate pre-signed URLs for downloading & uploading S3 objects.

    Here is a fully working example I wrote:

    // main.swift
    
    import AWSS3
    import Foundation.NSTimeZone
    
    let region = "eu-west-1"
    let expirationInSeconds : TimeInterval = 3600;
    
    let bucketName = "my-bucket-name"
    let objectName = "my-object-name"
    
    let putObjectRequest = PutObjectInput(bucket: bucketName, key: objectName)
    let uploadUrl = try await putObjectRequest.presignURL(config: S3Client.S3ClientConfiguration(region: region), expiration: expirationInSeconds);
    
    if let uploadUrl = uploadUrl {
        print("Upload URL: \(uploadUrl)")
    }
    
    let getObjectRequest = GetObjectInput(bucket: bucketName, key: objectName)
    let downloadUrl = try await getObjectRequest.presignURL(config: S3Client.S3ClientConfiguration(region: region), expiration: expirationInSeconds);
    
    if let downloadUrl = downloadUrl {
        print("Download URL: \(downloadUrl)")
    }
    
    // Package.swift
    
    // swift-tools-version: 5.9
    
    import PackageDescription
    
    let package = Package(
        name: "PackageName",
        platforms: [.macOS(.v10_15), .iOS(.v13)],
        dependencies: [
            .package(url: "https://github.com/awslabs/aws-sdk-swift.git", from: "0.27.0")
        ],
        targets: [
            .executableTarget(
                name: "ExecutableName",
                dependencies: [
                    .product(name: "AWSS3", package: "aws-sdk-swift")
                ],
                path: "Sources"
            )
        ]
    )
    

    Output:

    Upload URL: https://my-bucket-name.s3.eu-west-1.amazonaws.com/my-object-name?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxx%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20231012T154344Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=xxx

    Download URL: https://my-bucket-name.s3.eu-west-1.amazonaws.com/my-object-name?Bucket=my-bucket-name&Key=my-object-name&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxx%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20231012T154344Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=xxx

    Program ended with exit code: 0