Skip to content

Instantly share code, notes, and snippets.

@NSURLSession0
Created February 7, 2016 21:36
Show Gist options
  • Save NSURLSession0/87c144cec514c5ce73bd to your computer and use it in GitHub Desktop.
Save NSURLSession0/87c144cec514c5ce73bd to your computer and use it in GitHub Desktop.
CloudKit server-to-server in PHP
<?php
// Constants
$KEY_ID = 'YOUR_KEY_ID';
$CONTAINER = 'YOUR_CONTAINER';
$PRIVATE_PEM_LOCATION = 'eckey.pem'; // Store this file outside the public folder!
// Config
$url = 'https://api.apple-cloudkit.com/database/1/' . $CONTAINER . '/development/public/records/query';
$body = '{"query":{"recordType":"Articles"}}';
// Set cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Create signature
date_default_timezone_set('UTC');
$explode_date = explode('+', date("c", time()));
$time = $explode_date[0] . 'Z';
$signature = $time . ":" . base64_encode(hash("sha256", $body, true)) . ":" . explode('cloudkit.com', $url)[1];
// Get private key
$pkeyid = openssl_pkey_get_private("file://" . $PRIVATE_PEM_LOCATION);
// Sign signature with private key
if(openssl_sign($signature, $signed_signature, $pkeyid, "sha256WithRSAEncryption")) {
openssl_free_key($pkeyid);
// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER,
[
"Content-Type: text/plain",
"X-Apple-CloudKit-Request-KeyID: " . $KEY_ID,
"X-Apple-CloudKit-Request-ISO8601Date: " . $time,
"X-Apple-CloudKit-Request-SignatureV1: " . base64_encode($signed_signature),
]
);
// Set body
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
// Send the request & save response to $resp
$resp = curl_exec($ch);
if(!$resp) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
} else {
$json_result = json_decode($resp);
echo '<pre>';
var_dump($json_result);
}
curl_close($ch);
} else {
while ($msg = openssl_error_string()) {
echo $msg . "<br />\n";
}
}
@malhal
Copy link

malhal commented Apr 4, 2016

Thanks a lot for figuring this out, I've slotted it into code I already had for communicating with a similar backend and uploaded this new CloudKit-PHP project.

@inPhilly
Copy link

Can this code be used to update a CKAsset field on a record?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment