"Clash of Clans" uses Game Center to authenticate and link a player with an existing remotely stored game state.
From what I can see, a game is only provided a player identifier on client side. Is there a supported technique to securely authenticate a user instead of sending just the identifier (which is an equivalent of authenticating with just a username)?
Since I asked the question, Apple has introduced a new API and the answer is available on: Setting up third-party server to interact with Game Center (thank you, user2949759) and on a few other places.
Specifically, since iOS 7 (Apple documentation on Wayback Machine):
-[GKLocalPlayer generateIdentityVerificationSignatureWithCompletionHandler:]
Generates a signature that allows a third party server to authenticate the local player.
The relevant callback block's arguments include NSURL *publicKeyUrl
, NSData *signature
, NSData *salt
, uint64_t timestamp
. These, along with player's playerID
and bundleID
, should be shipped off to the server as the 'login information'.
publicKeyURL
to obtain the public keyplayerID
, bundleID
, big-endian uint64
timestamp, and verbatim salt
digest
signature
that was shipped to the server is correct, using the public key downloaded earlier, the signature
and the digest
There's an example in pseudo-PHP, an example of how one would implement this in Objective-C (which makes little sense to use verbatim), a Go implementation, a Ruby implementation and there is an assortment of implementations in other languages on that same question.
Unsurprisingly, the implementation in Go seems particularly readable, but it doesn't verify that the public key was issued by Apple. Linked Ruby implementation contains a rather clear example of how to do that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With