Sign In Register

How can we help you today?

Start a new topic
Answered

Preventing concurrent login II

I understand there are other forum entries handling the same topic, but they are all marked as answered without giving me a satisfying way on how to actually achieve this. 


Like multiple users stated here, it is necessary for many other people as well to prevent users from logging in with the same account (on same or different device) at the same time. Sure, we could adept our backend code to sync all connected devices, but for us that just means allot of more work, trouble, risk and time without having a real benefit for our game vision. 


Like other users stated, it would be best for us as well to just set a flag somewhere in the backend and - bang - multiple loggins are just forbidden globally.


Or can you please give us an idea on how to handle it on our own: In the AuthenticationRequest cloud code script, how can I load a player by name and password to check if he is already online to let the request fail?


Best Answer

Hi Fiete,


Apologies that no one has got back to you sooner about this. Spark.getPlayer().disconnect(true) in the AuthenticationResponse would be the correct way to handle this. As Roman mentions above, this will log the player out on all of the other devices and the latest one will be able to Authenticate and continue on in the game. You can't avoid having both instances of the players logged in at some stage, it has to happen if you want to disconnect the older sessions.


Roman if you don't want the latest player to authenticate you could place a check in scriptData if Spark.getPlayer().getScriptData(userLoggedIn) is 'true', you could set this in a successful AuthenticationResponse then check it each time after. If userLoggedIn = true you could throw an error to prevent authentication from continuing or prompt the user to disconnect all of the other instances of that player with Spark.getPlayer().disconnect(true). Hope this helps.


Thanks,

Liam


4 people have this question

Hi Fiete,


Have you considered the SessesionTerminatedMessage suggested by Sean in that linked thread?

Might be the best way to go about it currently.


Oisin

Hi Oisin,

thank you for your fast answer. I understand I can use Spark.getPlayer().disconnect(true) to disconnect a loaded player. This will probably send a SessionTerminatedMessage to client, which will handle stuff there.

But my question originally aimed on the concept of how to identify (then load and disconnect) a player which is connected already:

If I do the isOnline check in AuthenticationRequest, the player is not loaded yet in this scope, doing it in the AuthenticationResponse seems to be to late already since the player might be connected twice already then.

Would you always send a SessionTerminatedMessage in the AuthenticationRequest, without checking if it is even necessary?

Feels like I still miss the point of matter..

 

Bump..


Customer support, please react!


As you can see here this is a big problem for many gamesparks users!


Bump. I'm weighing in -- we have spent way too much time on this one issue already. Like fiete said -- it's a big problem for many developers, and it desperately needs a solution.

This is an important topic for us too, I would also need a solution or at least a code example based on SessionTerminatedMessage.

Thanks

Well, what I am currently doing when there is a concurrent login, is to call disconnect() in cloud every time player authenticates. This sends SessionTerminatedMessage to the currently logged in player, and new one is authenticated. The old player's code handles the message and notifies player about concurrent login and "logs him out". Problem with this is now I have to go through all the possible game states and try to handle that message gracefully.

Ideally, when authenticating, I would like SPARKS to check if there this account is logged in already and send message back that login is currently not allowed.

Oisin, the rest of the customer service!

Why don't you answer? I see other post getting a response, what is going on here? Do we have to collect signatures? Bribes..?

At least tell us you don't know or you gonna ask somebody, but letting us wait like this, in my opinion, is quite rude and unprofessional.

I am sorry, but until now I actually had a very good experience with the GameSparks' customer service, please don't make me change my good impression.

Thanks, Fiete

 

Answer

Hi Fiete,


Apologies that no one has got back to you sooner about this. Spark.getPlayer().disconnect(true) in the AuthenticationResponse would be the correct way to handle this. As Roman mentions above, this will log the player out on all of the other devices and the latest one will be able to Authenticate and continue on in the game. You can't avoid having both instances of the players logged in at some stage, it has to happen if you want to disconnect the older sessions.


Roman if you don't want the latest player to authenticate you could place a check in scriptData if Spark.getPlayer().getScriptData(userLoggedIn) is 'true', you could set this in a successful AuthenticationResponse then check it each time after. If userLoggedIn = true you could throw an error to prevent authentication from continuing or prompt the user to disconnect all of the other instances of that player with Spark.getPlayer().disconnect(true). Hope this helps.


Thanks,

Liam

Hi Liam,


thank you for your answer =D


Just for clarification:


Use case I - Latest user first (disconnect old player when new one authenticates)


  1. Call Spark.getPlayer().disconnect(true); in the AuthenticationResponse

  2. This will send a SessionTerminatedMessage to the currently logged-in player. This message should be handled by the client, i.e. showing a message, changing game states, terminating the game or whatsoever.


Use case II - Keep old user (prevent new logins while player is connected)


  1. Set a bool in the player's script data indicating that the player is currently connected when the player authenticates (AuthenticationResponse):

    Spark.getPlayer().setScriptData("IsLoggedIn", true);

  2. Set it to false or remove it when the player disconnects (GS_PLAYER_DISCONNECT aka "Player Disconnected" system event):

    Spark.getPlayer().removeScriptData("IsLoggedIn");

  3. Finally throw an error when a player logs in and is connected already:

    var IsLoggedIn = Spark.getPlayer().getScriptData("IsLoggedIn");
    if (IsLoggedIn !== null && IsLoggedIn) throw "ALREADY_LOGGED_IN";

For me that works fine, (@followers:) anybody else needs more information?



3 people like this

We assign the user an ID when they login, which is then passed to any sensitive cloud code functions. The ID is then checked to make sure it matches the latest one generated, and if it does not, the cloud code returns with an invalid login, and the game displays a message to the user that they have logged in elsewhere. This was the technique we used on our old database before we migrated to GameSparks.

Hi, 


I implemented this technique, and it works quite well.

Spark.getPlayer().disconnect(true); in the AuthenticationResponse

 


But very often I have this fatal error on this line :

{"stackTrace":"\tat 296608-response-AuthenticationResponse:5\n","error":"TypeError: Cannot call method \"disconnect\" of null (296608-response-AuthenticationResponse#5)","script":"AuthenticationResponse"}


How can the Spark.getPlayer() be null in the AuthenticationResponse ?

How can I fix that ?

 

Thanks

Eric

Hi Eric,


The only way you'd get null in the AuthenticationResponse would be if there was an error Authenticating, examples of this would include using an invalid token for a social auth or a bad userName/password combination. You do have quite a few failed FacebookConnectReqeusts in your game which look like the cause of the issue you are having.


Thanks,

Liam

This probably happens when there is no user logged at the time, so the usual case.

We are using this code with a simple null check:
if (Spark.getPlayer() !== null)
    Spark.getPlayer().disconnect(true);

 

 

Thanks both for advice :)

Login to post a comment