Skip to content

Verifying Players

If your game has its own backend — saving progress server-side, running a shop, awarding anything of value — it must not take the player's identity from the game client. Verify it against Y8 instead.

The player object is display data, not proof of identity

Everything the SDK gives you about the signed-in player, the pid included, lives in the browser and can be modified by whoever is playing. It is there so you can greet someone by name and show their avatar.

A player who edits their pid before your game sends it to your server is then, as far as your server knows, somebody else.

If your game has no backend of its own, there is nothing to do here — the SDK already authenticates every call it makes to Y8 on your behalf.


How it works

Three steps, and the important part is that step 3 happens on your server, not in the game:

  1. The player signs in and the SDK reports it.
  2. The game asks the SDK for the player's access token and sends that token — and nothing else — to your backend.
  3. Your backend asks Y8 who the token belongs to, and believes Y8's answer.

The token is the only thing that crosses. Your backend never receives a player id from the client, so there is nothing for a player to tamper with.


Step 1 and 2 — in the game

const accessToken = y8Sdk.getAccessToken();

if (accessToken) {
    await fetch("https://your-game-backend.example/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ accessToken }),
    });
}

getAccessToken() is synchronous and returns null when nobody is signed in, so call it after authentication has been reported.

Send the access token, never the full token object

There is also a getToken() method, which returns the whole token object including the refresh token. A refresh token can mint new access tokens, so it must never leave the SDK — not to your own backend, not anywhere. getAccessToken() returns only the single string your server needs.

Server-side verification is not available on this platform: the Unity bridge does not expose the access token to C#.

A Unity game that needs a verified player identity on its own backend has to reach the SDK directly through a custom JavaScript plugin. If that is blocking you, contact Y8 support so it can be weighed for a future release.

Server-side verification is not available on this platform: the Construct 3 integration does not expose the access token to the event sheet.

If you need a verified player identity on your own backend, contact Y8 support so it can be weighed for a future release.

Server-side verification is not available on this platform: the Haxe wrapper does not expose the access token.

If you need a verified player identity on your own backend, contact Y8 support so it can be weighed for a future release.


Step 3 — on your server

Ask Y8 who the token was issued to:

GET https://account.y8.com/api/profile
Authorization: Bearer <access_token>

A 200 response describes the player the token actually belongs to:

{
  "pid": "…",
  "name": "…",
  "client_id": "…"
}

Then, on your server:

  1. Use the pid from this response. Ignore any identity the client sent alongside the token.
  2. Check that client_id equals your own App ID. Reject the login if it does not — see below.
  3. On 401, reject the login. The token is invalid or expired. Have the game call refreshToken() and retry once with the new token.
  4. Verify on every sign-in, not once per account, then issue your own session keyed to the verified pid.

Why the client_id check matters

Access tokens are issued per application. Without step 2, a token obtained from a different game could be replayed against your backend, and the profile lookup would succeed — it is a perfectly valid token, just not one issued to you. Comparing client_id to your own App ID is what makes the check specific to your game.


What to store

Store the verified pid and key your own records to it. It is stable for a player across sessions and games.

Do not store the access token as a long-lived credential. It expires, and once your own session exists you no longer need it — you have already established who the player is.