Generates V4 authorization headers and pre-signed URLs for authenticating AWS S3 REST API calls
Check out VaporS3Signer if your using Vapor
.
- Pure Swift
- All required headers generated automatically
- V4 Authorization header
- V4 pre-signed URL
- Support DELETE/GET/HEAD/PUT/POST
- Single chunk uploads
- Multiple chunk uploads
Swift Package Manager
To install with swift package manager, add the package to your Package.swift
file:
Import PackageDescription
let package = Package(
name: "Your_Project_Name",
targets: [],
dependencies: [
.Package(url: "https://github.com/JustinM1/S3SignerAWS.git", majorVersion: 3)
]
)
NOTE ABOUT PAYLOAD:
Requests can either have a signed payload or an unsigned payload.
- S3SignerAWS is built using
Vapor Server
frameworkCrypto
and usesBytes
as the payload data type.Bytes
is a typealias of[UInt8]
For example, to convert a data object to bytes you do the following:
let bytes = try someDataObject.makeBytes()
-
If you know the request will not have a payload, set the Payload property to none. This tells s3 that the signature was created with no payload intended
-
If you are not sure what the exact payload will be, set payload property to unsigned. This tells s3 when you made the signature, there was a possibility of a payload but you weren't sure what specific object will be uploaded.
-
Payload
enum:public enum Payload { case bytes(Bytes) case none case unsigned }
To begin working with the S3SignerAWS class, initialize an instance similar to example shown below:
let s3Signer = S3SignerAWS(accessKey: "YOUR_AWS_PUBLIC_KEY", secretKey: "YOUR_AWS_SECRET_KEY", region: .usStandard_usEast1)
NOTE - Hardcoding Secret Keys on client is not recommended for security reasons.
For both V4 Authorization Header and Pre-Signed URL, you can add additional headers as needed for your specific use case.
GET
do {
guard let url = URL(string: "https://s3.amazonaws.com/bucketName/testUploadImage.png") else { throw someError }
let headers = try s3Signer.authHeaderV4(httpMethod: .get, urlString: url.absoluteString, headers: [:], payload: .none)
var request = URLRequest(url: url)
request.httpMethod = HTTPMethod.get.rawValue
headers.forEach { request.setValue($0.key, forHTTPHeaderField: $0.value) }
// make network request
} catch {
//handle error
}
}
PUT
do {
let bytesObject = try someDataObject.makeBytes()
guard let url = URL(string: "https://s3.amazonaws.com/bucketName/testUploadImage.png") else { throw someError }
let headers = try s3Signer.authHeadersV4(httpMethod: .put, urlString: url.absoluteString, headers: [:], payload: .bytes(bytesObject))
var request = URLRequest(url: url)
request.httpMethod = HTTPMethod.put.rawValue
request.httpBody = Data(bytes: bytesObject)
headers.forEach { request.setValue($0.key, forHTTPHeaderField: $0.value) }
// make network request
} catch {
//handle error
}
}
DELETE
do {
guard let url = URL(string: "https://s3.amazonaws.com/bucketName/testUploadImage.png") else { throw someError }
let headers = try s3Signer.authHeadersV4(httpMethod: .delete, urlString: url.absoluteString, headers: [:], payload: .none)
var request = URLRequest(url: url)
request.httpMethod = HTTPMethod.delete.rawValue
headers.forEach { request.setValue($0.key, forHTTPHeaderField: $0.value) }
// make network request
} catch {
//handle error
}
}
Similar to the ease of generating authentication headers, to generate a pre-signed url:
let presignedURL = signer.presignedURLV4(httpMethod: HTTPMethod, urlString: String, expiration: TimeFromNow, headers: [String: String]) -> String