Players

Signing a player in

Anonymous, Steam, s&box or a dasmaffin.com account, and staying signed in.

Every way in ends with the same answer:

{
  "playerId": "6f0c1c9e-0b5e-4c8f-9a0e-3f1d2c4b5a69",
  "sessionToken": "mgds_...",
  "expiresAt": "2026-10-24T13:00:00Z",
  "refreshToken": "mgdsr_...",
  "refreshExpiresAt": "2027-01-22T12:00:00Z",
  "displayName": "Maffin",
  "created": false,
  "deviceKey": null,
  "idToken": "eyJhbGciOiJSUzI1NiIs..."
}

201 when the player was just made, 200 when they already existed. Signing in again never makes somebody new: it is the same player, with a new session.

  • sessionToken is the access token. Send it with every call as Authorization: Bearer <sessionToken>. It works for one hour (expiresAt).
  • refreshToken gets the next pair. Keep it - after a restart too - and use it instead of signing in again. It is single use.
  • idToken says who the player is, signed by us, for your own game server. See Your server: who is this player?. Every refresh brings a new one.

Staying signed in

POST /auth/refresh
{ "refreshToken": "mgdsr_..." }

Answers exactly like signing in: a new access token and a new refresh token. Throw the old refresh token away; it has just been retired. Refresh when a call answers 401, or shortly before expiresAt. The session lasts as long as it is refreshed at least every 90 days (refreshExpiresAt), so somebody who plays regularly is never asked to sign in again.

A refresh token is good once. If one that was already traded in turns up again, two copies of it exist and one of them is not the player's - so MGDS ends that whole session, for both, and the player signs in again. A stolen token is therefore noticed the next time either side refreshes, instead of working quietly for months. The one exception is a retry: the same refresh token again within 30 seconds (an answer lost on the way back) is answered with a fresh pair, and the pair it replaced stops working.

When /auth/refresh answers 401, sign in again.

Tokens are bearer credentials: whoever holds one is that player. Keep the refresh token where the game keeps its other private data, and the access token in memory.

Anonymous

POST /auth/anonymous
{ }

Makes a new player and returns a deviceKey with the session. Store the device key on the device; it is the only way back to this player, and it is shown once. Next time:

POST /auth/anonymous
{ "deviceKey": "..." }

401 if the key is unknown.

Steam

Ask Steam for a ticket for the identity mgds (ISteamUser::GetAuthTicketForWebApi("mgds")), wait for the ticket callback, and send its bytes as hex:

POST /auth/steam
{ "ticket": "140000006a..." }

401 if Steam does not accept it. Needs Steam added as a provider on the project's Authenticate page, with its app id and publisher key.

s&box

For a game made in s&box, which is not a Steam app of its own and so has no app id or publisher key. The game asks s&box for a token and sends it with the player's SteamID:

var token = await Sandbox.Services.Auth.GetToken( "mgds" );
POST /auth/sbox
{ "steamId": "76561198000000001", "token": "..." }

MGDS asks Facepunch whether the token is real and belongs to that SteamID; 401 if not. The token is valid for two minutes, so ask for it just before signing in. Needs s&box added as a provider on the project's Authenticate page; there is nothing to set up.

Steam and s&box both prove a SteamID, so somebody who plays both the s&box version and a Steam build of the same game is one player, with a login for each: logins lists "steam" and "sbox" separately, so which way a player came in is always known.

Facepunch's check does not include the service name the token was asked for, so a token a player gave another s&box game's backend could be replayed here within those two minutes. That is how s&box tokens work.

dasmaffin.com account

The player signs in in their browser; the game waits for the result.

  1. Start it:

    POST /auth/dasmaffin
    { }
    
    { "requestId": "...", "pollToken": "...", "url": "https://www.dasmaffin.com/Mgds/SignIn/...",
      "expiresAt": "...", "pollEverySeconds": 2 }
    
  2. Open url in the player's browser (or the Steam overlay's browser).

  3. Every pollEverySeconds, ask:

    POST /auth/dasmaffin/poll
    { "requestId": "...", "pollToken": "..." }
    
    Code Meaning
    202 Not yet. Ask again.
    200 / 201 Signed in: the session, as above. Collected once.
    403 They chose not to allow it.
    410 Expired (10 minutes), or already collected. Start again.

The game never sees the player's dasmaffin.com password or tokens: MGDS signs them in through the site's own sign-in for other programs and hands the game an MGDS session.