mojira.dev
MCL-1513

Access token gets invalidated after logging in on a different computer

Using token-based login with one Minecraft account on two computers has become impossible. As soon as the second client logs in, the first's access token gets invalidated, prompting the user for the password on the next launch.

Steps to reproduce:

  • Start client 1 on computer 1

  • Log in on client 1

  • Close client 1

  • Start client 2 on computer 2

  • Log in on client 2 using the same account as on client 1

  • Close client 2

  • Start client 1 on computer 1

Linked issues

Comments 7

Hmm... I was under the impression that the clientToken was supposed to allow separate accessToken sequences for the same user, so they could remain logged into multiple devices. Did you copy your launcher_profiles.json from one computer to another? They should have different clientTokens. If they are the same, delete the whole clientToken line from launcher_profiles.json on one computer, and the server will generate a new one. This will invalidate all your accessTokens, but I believe once you log in again on each computer, they should both be able to stay logged in.

I'm pretty sure the system worked the way you're describing it at some point in the past, but somehow that changed. The issue was discovered by a developer (dividuum) who was playing around with mc4p's authentication module (which uses a random client token), but I was able to reproduce it with vanilla clients (with different client tokens).

Can't reproduce. Works 100% fine here, using the normal launcher & even just doing the calls myself:

/authenticate user+pass clientToken-A => authTokenA
/authenticate user+pass clientToken-B => authTokenB
/validate clientToken-A authTokenA => good
/validate clientToken-B authTokenB => good

I did some more testing and found out that it only happens when using the (optional?) agent field:

Login with first client

curl https://authserver.mojang.com/authenticate --data-binary '{"clientToken":"1","username":"[email protected]","password": "*****","agent":{"name":"Minecraft","version":1}}' -H "Content-Type: application/json"
{"accessToken":"c7e61ccbe6d3444db4506224b260a491","clientToken":"1","selectedProfile":{"id":"********************************","name":"sadimusi"},"availableProfiles":[{"id":"********************************","name":"sadimusi"}}

Login with second client

curl https://authserver.mojang.com/authenticate --data-binary '{"clientToken":"2","username":"[email protected]","password": "*****","agent":{"name":"Minecraft","version":1}}' -H "Content-Type: application/json"
{"accessToken":"17aca929de854990836aae6f6f0ac8ba","clientToken":"2","selectedProfile":{"id":"********************************","name":"sadimusi"},"availableProfiles":[{"id":"********************************","name":"sadimusi"}}

Validate second client's access token

curl https://authserver.mojang.com/validate --data-binary '{"accessToken": "17aca929de854990836aae6f6f0ac8ba"}' -H "Content-Type: application/json"

Validate first client's access token

curl https://authserver.mojang.com/validate --data-binary '{"accessToken": "c7e61ccbe6d3444db4506224b260a491"}' -H "Content-Type: application/json"
{"error":"ForbiddenOperationException","errorMessage":"Invalid token"}

Maybe this is an easy way to reproduce this problem:

  • Log in to Minecraft using the normal launcher

  • Connect to any server that requires authentication -> works

  • Disconnect from that server

  • Do an authenticate request to authserver.mojang.com:

    curl https://authserver.mojang.com/authenticate --data-binary '{"username":"XXXXXXX","password": "XXXXXX", "clientToken": "01234567890123456789012345678901", "agent":{"name":"Minecraft","version":1}}' -H "Content-Type: application/json"

    The username in my case is my converted mojang account, so I'm using my email address. Note that I'm sending a (made up) clientToken. This, according to http://wiki.vg/Authentication, shouldn't invalidate any other accessTokens.

  • The authenticate call succeeds:

    {"accessToken":"e866XXXX","clientToken":"0123...","selectedProfile":{"id":"035XXX","name":"dividuum"},"availableProfiles":[{"id":"035XXX","name":"dividuum"}]}
  • In the open Mincraft Client, try to connect to the same server as previously -> Bad Login (why?)

  • Close Minecraft ("Quit Game")

  • Restart the Launcher. It will say "You're already logged in as <your username> in another profile".

  • Log back in.

  • In the Development Console will be this messages:

    Refresh complete.
    Loaded 1 profile(s); selected 'dividuum'
    Refreshing auth...
    Logging in with access token
    net.minecraft.launcher.authentication.exceptions.InvalidCredentialsException: Invalid token.
    	at net.minecraft.launcher.authentication.yggdrasil.YggdrasilAuthenticationService.makeRequest(YggdrasilAuthenticationService.java:118)
            ....
    Delta time to compare resources: 457 ms 
    Download job 'Resources' skipped as there are no files to download
    Job 'Resources' finished successfully
    Logging in with username & password

This leads to the following questions:

  • This looks like the previous accessToken got invalidated by the authenticate request. Is that correct?

  • How many accessToken can be active at the same time for a user? Is this limited somehow?

  • What does the "You're already logged in ..." error message mean? How is being logged in determined?

  • Do I have to signout somehow, so other accessTokens can be reused?

  • Are there any requirements for a clientToken (length, etc..)?

  • I only have a converted mojang account. Maybe it works for non-converted accounts?

  • Is this the intended behavior?


Other observations:

  • Omitting the agent field works and doesn't seem to invalidate the existing session but provides no profile id information, so it's not possible to create a session token which is needed for login.

Thanks for any feedback.

I am still seeing this same issue. Login from 2 different PC's and one PC invalidates the other access token. Is this intended or is there still an issue?

This bug is fixed now. The problem was that I hit the client-/accessToken limit. Once that happened the auth server was supposed to remove the oldest token. Instead it removed the newest token which resulted in the observed behavior. This bug is fixed now. Everything works as expected now.

Simon Marti

(Unassigned)

Unconfirmed

yggdrasil

Retrieved