question

info-2 avatar image
info-2 asked

Time-limited Account Link Code (How?)

Hi all,

my scenario is the following: linking devices on the same platform (e.g. Android -> Android) is not an issue, since this is covered via LinkGoogleAccount etc. Linking devices cross-platform (e.g. Android -> iOS) is not an issue either, provided that a top-level link for both platforms is supported (e.g. LinkFacebookAccount).

The scenario I'm having issues with is where such a top-level link (Facebook) is not supported, for example when linking from Steam to Android or vice-versa. I don't want to force players into registering a PlayFab account with email and password in this case. The system I'm having in mind is similar to the one Clash of Clans is using: if you want to link with an 'external' device, they create a code that is valid for 2 minutes. You enter this code on the new device, and your account is then linked to the old device successfully. There is a video showing this process here (https://www.youtube.com/watch?v=iVr70hWGv5M).

So, to implement something like this, I've thought about several techniques. First, AddUserNamePassword - as explained in this blog post (https://playfab.com/first-impressions-count-best-practices-friction-free-player-authentication/), is not a solution: device A would call AddUserNamePassword and display the password for device B. Since you can't change the password again without sending an email, the displayed credentials would be always valid i.e. never expire. There is no RemoveUserNamePassword method or way to 'unlink' this later either.

Second, a combination of CloudScript+UserInternalData+CustomID came to my mind. Device A calls ExecuteCloudScript that writes a key to the UserInternalData entry (automatically adds a timestamp value). Device A then calls LinkCustomID using a ID+Password string to create an access point for device B. Device B calls ExecuteCloudScript and checks the UserInternalData entry of the old account. If it's still within 2 minutes and the key matches, returns success and lets device B call LoginWithCustomId with the ID+Password displayed earlier on device A. After login, device B calls Link...DeviceID and UnlinkCustomId to remove the (now obsolete) previous login.

Actually, it would be a lot nicer if I would be able to let the server manage all the Link...DeviceID and UnlinkCustomID calls, but since CloudScript can't execute client API this seems like the way to go. Does that make any sense? How would you go about implementing a time-limited/secure cross-platform link system like Clash of Clans in PlayFab instead?

Best,

Florian

apisCloudScriptAccount Management
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
brendan avatar image
brendan answered

My recommendation would be to use Custom ID as the way to drive this - generate an ID, let the player use it to sign into the other account, then remove it. And yes, in order to time limit this, you would need to have a process somewhere keeping track of that time, whether on the client or a custom game server. Cloud Script is intended for light-weight operations triggered by a call from a client, a server, or a PlayStream trigger (Rule, Segment enter/exit, Task, etc.), and you are correct that it does not have the ability to unlink an account, so it wouldn't be the way to approach this. If your timer is managed by the client, then it is the case that there will be scenarios where the Custom ID is added to the account and then not removed after your time limit has passed, since the client may have disconnected, so it's also recommended that you use a sufficiently complex schema for the Custom ID, in order to prevent hackers from guessing those IDs.

6 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

info-2 avatar image info-2 commented ·

Thank you Brendan, nice to hear that I'm not completely off when using the second approach. You are right in that I need to make sure the Custom ID is complex enough to not guess it easily, and I think a combination of the PlayFab user ID + key is secure "enough". I have this full process working already using Cloud Script (and client calls for the linking).

0 Likes 0 ·
info-2 avatar image info-2 commented ·

Just one more thing: after implementing the timestamp checks for internal user data, I've found that I also need to provide the client with the PlayFab user ID, to actually be able to check this specific user data and see if the secret key expired. I guess there is no server method, that allows me to pass in a Custom ID, which then returns the PlayFab user ID it is currently linked to? (not talking about "generic service identifier" here, but the standard Custom ID used to login to accounts).

0 Likes 0 ·
brendan avatar image brendan ♦♦ info-2 commented ·

No, at the moment, you could use the Client API (GetPlayFabIDs...), but the CustomID version of that isn't in the Server API set. It will be soon, but if you need to enable this now, you would need to have the client query for that info and send it up as part of the call to Cloud Script.

0 Likes 0 ·
info-2 avatar image info-2 brendan ♦♦ commented ·

Unfortunately I am not able to find a GetPlayFabIDs... method for CustomID in the Client API either - there are only methods for social accounts such as Facebook, Google, etc. Please let me know when GetPlayFabID for CustomID is in the Server API set. Thanks again!

0 Likes 0 ·
Show more comments
info-2 avatar image info-2 commented ·

Thanks a lot Brendan (couldn't reply to your last comment for some reason). What I'm doing at the moment is to send the targeted PlayFab ID to Cloud Script, for the server to call GetInternalUserData and check against the timestamp & secret key - then log in after a successful result. So the verification does not happen on the client. It is indeed little difference in security, so I figured a GetPlayFabIDsFromCustomIDs call would make sense to have everything run on Cloud Script. Good to know it's coming at some point :)

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Error rendering WebPanel (widgets/consolidation-widget.ftl): org.hibernate.hql.internal.ast.QuerySyntaxException: AvailableConsolidation is not mapped [from AvailableConsolidation up where up.node = :node]