swiftcloudkitvaporecdsa

Server side Swift - help connecting to CloudKit Web Services


I'm trying to connect to ck web services using Vapor.

I keep getting code 401 (authentication failed). I read and reread the docs(https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitWebServicesReference/SettingUpWebServices.html#//apple_ref/doc/uid/TP40015240-CH24-SW1) a hundred times but still no luck

Here is my code:

let body = [
        "records":
            [
                ["recordName": "email@gmail.com"]
            ]
    ]
    let bodyData = try? JSONSerialization.data(withJSONObject: body)

    let requestBody = bodyData!
    let body64 = requestBody.base64EncodedString()

    let calendar = Calendar(identifier: .gregorian)
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
    dateFormatter.timeZone = calendar.timeZone
    let date = dateFormatter.string(from: Date())
    
    let webServiceURLPath = "/database/1/MYCONTAINERID/development/public/records/lookup"
    let message = date + ":" + "\(body64)" + ":" + webServiceURLPath
   
    let privateKeyPem =
        """
        -----BEGIN EC PRIVATE KEY-----
        MY PRIVATE HIDDEN PRIVATE KEY
        -----END EC PRIVATE KEY-----
        """
    
    let privateKey = try? P256.Signing.PrivateKey(pemRepresentation: privateKeyPem)
    let sign = try? privateKey?.signature(for: SHA256.hash(data: message.data(using: .utf8)!))
    let signatureBase64 = sign!.derRepresentation.base64EncodedString()

    let keyID = "MYKEYID"
    
    let url = URI(string: "https://api.apple-cloudkit.com/database/1/MYCONTAINERID/development/public/records/lookup")
    
    let headers = HTTPHeaders([
        ("X-Apple-CloudKit-Request-KeyID", keyID),
        ("X-Apple-CloudKit-Request-ISO8601Date", date),
        ("X-Apple-CloudKit-Request-SignatureV1", signatureBase64)
    ])
   
    let response = try app.client.post(url, headers: headers) { request in
        try request.content.encode(body)
    }
    response.flatMapThrowing({ response in
        print(response)
    })

Solution

  • I ended up switching to Node js, Vapor doesn’t have enough support and community members