Composing Web Service Requests
CloudKit web service URLs have common components. Always begin the endpoints with the CloudKit web service path followed by database
, the protocol version number, container ID, and environment. Then pass the operation subpath containing the credentials to access CloudKit using either an API Token or server-to-server key.
Use an API Token from a website or an embedded web view in a native app, or when you need to authenticate the user, described in Accessing CloudKit Using an API Token. If the request requires user authentication, use the information in the response to authenticate the user. Use a server-to-server key to access the public database from a server process or script, described in Accessing CloudKit Using a Server-to-Server Key.
Read the following chapters for the operation-specific JSON request and response dictionaries associated with each web service call.
The Web Service URL
This is the path and common parameters used in all the CloudKit web service URLs:
[path]/database/[version]/[container]/[environment]/[operation-specific subpath]
- path
The URL to the CloudKit web service, which is
https://api.apple-cloudkit.com
.- version
The protocol version—currently, 1.
- container
A unique identifier for the app’s container. The container ID begins with
iCloud.
.- environment
The version of the app’s container. Pass
development
to use the environment that is not accessible by apps available on the store. Passproduction
to use the environment that is accessible by development apps and apps available on the store.- operation-specific subpath
The operation-specific subpath (provided in the following chapters).
Accessing CloudKit Using an API Token
To access a container as a user, append this subpath to the end of the web service URL. Provide an API token you created using CloudKit Dashboard and optionally, a web token to authenticate the user.
?ckAPIToken=[API token]&ckWebAuthToken=[Web Auth Token]
- API token
An API token allowing access to the container. The
ckAPIToken
key is required.To create an API token, read Creating an API Token.
- Web Auth Token
The identifier of an authenticated user. The
ckWebAuthToken
key is optional, but if omitted and required, the request fails.To authenticate the user and retrieve this token, read Getting the Web Authentication Token.
Creating an API Token
Use CloudKit Dashboard to create the API token.
To create an API token
Sign in to CloudKit Dashboard.
In the upper left, from the pop-up menu, choose the container used by your app.
API tokens are associated with a container.
In the left column, click API Access.
In the heading of the second column, choose API Tokens from the pop-up menu.
Click the Add button (+) in the upper-left corner of the detail area.
Enter a name for the API token.
(Optional) Specify a custom URL that is loaded after the user signs in using his or her Apple ID.
In the Sign In Callback field, choose
http://
and enter a custom URL.(Optional) Restrict the domains that can access your app’s container using CloudKit web services.
In the Allowed Origins field, choose "Specific domains” and enter a domain.
(Optional) Enter a description in the Notes field.
Click Save.
Use and Duration of the Web Authentication Token
Each token is intended for a single round trip to the server. Whenever a token is sent to the server, a new token is provided in the response from the server. Once the response is received, the previous token is no longer valid. It must be discarded and the new, returned token used in the next request.
By default, the web authentication token expires 30 minutes after it is created. If the user selects “Keep me signed in” during the sign-in window, the duration of the token is 2 weeks.
Getting the Web Authentication Token
Some database operations require that users sign in using their Apple ID. Your web app will need to handle these authentication errors and present the user with a dialog to sign in. Apple will present the actual sign-in page through a redirect URL so that the user’s credentials remain confidential. If the user chooses to sign in, the response contains a web authentication token that you use in the subpath of subsequent requests.
To authenticate a user
Send a request (specifying the API token in the subpath) that requires a user to sign in.
An
AUTHENTICATION_REQUIRED
error occurs, and the response contains a redirect URL.For example, send a request to get the current user, and append the API token.
curl "https://api.apple-cloudkit.com/database/1/[container]/[environment]/[database]/users/current?ckAPIToken=[API token]"
The response contains a dictionary similar to this one:
{
"uuid":"4f02f7aa-fbb5-4cf8ae8e-4dd463793841",
"serverErrorCode":"AUTHENTICATION_REQUIRED",
"reason":"request needs authorization",
"redirectURL":"[redirect URL]"
}
If you did not specify a custom URL when creating the API token, register an event listener with the window object to be notified when the user signs in.
window.addEventListener('message', function(e) {
console.log(e.data.ckWebAuthToken);
})
Open the value for the
redirectURL
key that you received in the response.The Apple sign-in dialog appears displaying your app icon and name. If the user enters the Apple ID and password, the response contains a
ckWebAuthToken
string. If you specified a custom URL when creating the API token, theckWebAuthToken
string is passed to the custom URL, as inhttps://[my-callback-url]/?ckWebAuthToken=[Web Auth Token]
.Encode and append the
ckWebAuthToken
string that you received to future requests.To URL encode the
ckWebAuthToken
string, replace '+' with '%2B', '/' with '%2F', and '=' with '%3D'. For example, send a request to get the current user by appending theckWebAuthToken
string.curl "https://api.apple-cloudkit.com/database/1/[container]/[environment]/[database]/users/current?ckAPIToken=[API token]&ckWebAuthToken=[Web Auth Token]"
The request succeeds and the response contains the
userRecordName
key, described in Fetching Current User (users/current).
Accessing CloudKit Using a Server-to-Server Key
Use a server-to-server key to access the public database of a container as the developer who created the key. You create the server-to-server certificate (that includes the private and public key) locally. Then use CloudKit Dashboard to enter the public key and create a key ID that you include in the subpath of your web services requests.
See CloudKit Catalog: An Introduction to CloudKit (Cocoa and JavaScript) for a JavaScript sample that uses a server-to-server key.
Creating a Server-to-Server Certificate
You create the certificate, containing the private and public key, on your Mac. The certificate never expires but you can revoke it.
To create a server-to-server certificate
Launch Terminal.
Enter this command:
openssl ecparam -name prime256v1 -genkey -noout -out eckey.pem
A
eckey.pem
file appears in the current folder.
You’ll need the public key from the certificate to enter in CloudKit Dashboard later.
To get the public key for a server-to-server certificate
In Terminal, enter this command:
openssl ec -in eckey.pem -pubout
The public key appears in the output.
read EC key
writing EC key
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExnKj6w8e3pxjtaOUfaNNjsnXHgWH
nQA3TzMT5P32tK8PjLHzpPm6doaDvGKZcS99YAXjO+u5pe9PtsmBKWTuWA==
-----END PUBLIC KEY-----
Storing the Server-to-Server Public Key and Getting the Key Identifier
To enable server-to-server API access, enter the public key in CloudKit Dashboard. Later, you’ll use the key ID generated by CloudKit Dashboard in the subpath of your web services requests.
To add a server-to-server key to the container
Sign in to CloudKit Dashboard.
In the upper left, from the pop-up menu, choose the container used by your app.
In the left column, click API Access.
In the heading of the second column, choose Server-to-Server Keys from the pop-up menu.
Click the Add button (+) in the upper-left corner of the detail area.
Enter the public key for the server-to-server key that you created in Creating a Server-to-Server Certificate.
(Optional) Enter notes.
Click Save.
Use the identifier that appears in the Key ID field in your requests. If you are using web services, pass the key ID as the
X-Apple-CloudKit-Request-KeyID
property in the header of your signed requests, described in Authenticate Web Service Requests. If you are using CloudKit JS, set theserverToServerKeyAuth.keyID
field in theCloudKit.ContainerConfig
structure to the key ID.
Authenticate Web Service Requests
When using a server-to-server key, you sign the web service request.
To create a signed request using the server-to-server certificate in your keychain
Concatenate the following parameters and separate them with colons.
[Current date]:[Request body]:[Web service URL subpath]
- Current date
The ISO8601 representation of the current date (without milliseconds)—for example,
2016-01-25T22:15:43Z
.- Request body
The base64 string encoded SHA-256 hash of the body.
- Web service URL subpath
The URL described in The Web Service URL but without the
[path]
component, as in:/database/1/iCloud.com.example.gkumar.MyApp/development/public/records/query
Compute the ECDSA signature of this message with your private key.
Add the following request headers.
X-Apple-CloudKit-Request-KeyID: [keyID]
X-Apple-CloudKit-Request-ISO8601Date: [date]
X-Apple-CloudKit-Request-SignatureV1: [signature]
- keyID
The identifier for the server-to-server key obtained from CloudKit Dashboard, described in Storing the Server-to-Server Public Key and Getting the Key Identifier.
- date
The ISO8601 representation of the current date (without milliseconds).
- signature
The signature created in Step 2.
For example, this curl
command creates a signed request to lookup email addresses.
curl -X POST -H "content-type: text/plain" -H "X-Apple-CloudKit-Request-KeyID: [keyID]” -H "X-Apple-CloudKit-Request-ISO8601Date: [date]" -H "X-Apple-CloudKit-Request-SignatureV1: [signature]" -d '{"users":[{"emailAddress":"[user email]"}]}' https://api.apple-cloudkit.com/database/1/[container ID]/development/public/users/lookup/email
Copyright © 2018 Apple Inc. All rights reserved. Terms of Use | Privacy Policy | Updated: 2016-06-13