24

I'm wanting to allow users to create an account on my server automatically using their Game Center account. When my iOS app opens up it requires a connection and authentication with an XMPP server in order to communicate with the game server. I'm trying to find something in GKLocalPlayer that is private to a logged in device that I could use to create/validate a remote user login, but the only thing that seems to be unique to the player is their playerID which is fairly public.

I don't really want to use GameCenter for everything because then it partitions my user base to only iOS devices.

From developer.apple.com

... if your application connects to your own network services, you can use the player identifier on your service to save data there as well.

Since the player identifier isn't private, how sure can we be sure that this isn't being faked?

Kendall Hopkins
  • 43,213
  • 17
  • 66
  • 89
  • How is a player ID not private? – Moshe Feb 24 '11 at 17:54
  • @Moshe For a few reasons. It's not unique to my game, so any other game could have access to it. You can also query for your friends playerID using `loadFriendsWithCompletionHandler:` and I believe they are also available via the leader board. I'm sure GameCenter uses an internal secret to ensure that it's logged in when making the requests, but since I don't have access to it, I seem to have no way to validate a GameCenter login from a thirdparty server. – Kendall Hopkins Feb 24 '11 at 18:21

3 Answers3

7

Everything in GKLocalPlayer can be faked. Same can be said for UIDevice.

A better strategy is to assign private session data to each device that connects and provide means to link device sessions to accounts via a verification email. Perhaps include the playerID to allow interaction with GameKit data, but not as a means of identification.

rpetrich
  • 32,196
  • 6
  • 66
  • 89
3

Looks like this is possible since iOS 7 using:

[localPlayer generateIdentityVerificationSignatureWithCompletionHandler]

https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html

andyzinsser
  • 2,463
  • 2
  • 18
  • 18
0

I'm not sure that the player ID can be faked, but you could generate a key based on that along with the other unique ID that iOS users have: thier UDID. When a player successfully logs in to Game Center, generate a key based on the UDID. If it matches a stored value, you're golden. If not, it's likely the user on anther device since they've successfully logged in to game center. In that case, offer to add it. To prevent session hijacking, have the user confirm bew devices via email. This only works for iOS devices though, since it is tied to game center and UDID.

An alternative, which can handle other platforms as well, is to have your game contact your server on the first run and pull a generated unique ID from your server. Whenever your app reports a score (or anything else) you send your own ID. There are ways to encrypt that data, but I'm not even an amateur in that area. I know nothing of use there. (If you want, look into sending "API keys" along with your request or sending "salted hash"es. but I have no idea what that would do for you. I've heard of those before and suspect that that may help.)

Moshe
  • 57,511
  • 78
  • 272
  • 425
  • "If not, it's likely the user on anther device since they've successfully logged in to game center. In that case, offer to add it." Or it could be a "hacker" trying to gain access to their account just by presenting their playerID. Adding the UDID doesn't really add anything in this case unless I'm willing to lock their login to 1 device (which i don't really want to). – Kendall Hopkins Feb 24 '11 at 17:46
  • Sort of. You should be checking that `localPlayer.isAuthenticated` is true before doing anything anyway. Game Center handles that. What about the second part? Generate your own ID server side. There is always a risk of session hijacking. A confirmation email help with this. – Moshe Feb 24 '11 at 17:52
  • In order to talk to my server I'm going to do a HTTP hit to PHP where I will pass the required information to do authentication or registration via GameCenter. I can't depend on the client to tell the truth about it's own isAuthenticated variable. – Kendall Hopkins Feb 24 '11 at 18:16