This is the exact flow that runs when a signed-in avogames player presses Play on matchess. It is the reference integration: matchess verifies the identity in both places — offline on its own server, then again against avogames — and binds the account by global_id so the player keeps their progress every time they come back.
1. The player signs in on avogames
- Login mints the session (
SessionController.create):authenticated = true, the account'suser_id, a freshlogin_session=bcrypt(user_id + SESSION_KEY), and a fresh randomtokenwritten onto the account. - Guests get the same shape (
GuestService), so even a visitor who never registers has a real account behind the game.
2. The play page hands the identity to the frame
Opening /games/matchess finds matchess' production build and appends the session to its iframe URL (GamesController.withPlayerIdentity). The frame loads something like:
https://<matchess-host>/play
?user_id=<avogames user_id>
&login_session=$2a$10$<hash of user_id + SESSION_KEY>
&token=<current token>
&platform=avogames
&from_global=1
3. matchess' backend verifies and binds
- The request passes matchess'
sessionAuthpolicy, which routes it throughSessionService.proceed_request. Seeingfrom_global, it runsglobal_login_flow. - First, offline:
bcrypt.compare(user_id + bcrypt_hash_key, login_session).bcrypt_hash_keyis avogames'SESSION_KEY, so this proves the identity is genuine with no network call. - Then it looks up a local account by
global_id= the avogamesuser_id. A returning player is found here and signed straight in. - A first-time player is not — so matchess calls back to
POST /validate_global_token(the same endpoint as/get_user_data) with{ api_key, user_id, token }. avogames returns the account only while the token is current. matchess links onto an existing local account by steam_id or email, or registers a fresh one carryingglobal_id. - matchess mints its own
session_id(bcrypt of its session secret + the local user id), setsuser_id+session_idon the session, and the page renders them into hidden inputs.
The code matchess actually runs — SessionService.global_login_flow, trimmed to the essentials (platform, locale and publisher are resolved earlier in the function):
// SessionService.global_login_flow - matchess, trimmed to the essentials
const valid = await bcryptjs.compare(
req.query.user_id + Config.params().bcrypt_hash_key,
req.query.login_session
);
if (!valid) return { error: "wrong_user_connection_1" };
let user = (await User.find({ global_id: req.query.user_id, server: 1 }))[0];
if (!user) {
// first visit: pull the authoritative account from avogames
const resp = await request_global_server(
{ api_key: Config.params().secret_key,
user_id: req.query.user_id,
token: req.query.token },
"validate_global_token",
platform === "avogames" ? "https://avogames.com/" : undefined
);
const g = resp && resp.data && resp.data.user;
if (g && g.email) user = (await User.find({ email: g.email.toLowerCase(), server: 1 }))[0];
if (!user) user = await global_local_registration_flow(req, locale, platform, publisher);
}
const session_id = await bcryptjs.hash(sails.config.session.secret + user.id, 10);
return {
session: {
authenticated: true, user_id: user.id, session_id: session_id,
publisher: "global", global_session_id: req.query.login_session,
}
};
4. matchess' frontend carries the session
- Boot code reads the hidden inputs into
socket_params = { user_id, session_id }. - Every request the game makes carries them, and
sessionAuthre-verifies thesession_ideach time. The player is fully signed in — inventory, progress, everything — on their avogames account.
5. Every other game, the same account
The same login_session + token are appended to every game's iframe URL. Each game runs the same two checks and stores the same global_id, so the account an avogames player is signed into anywhere on the platform is their one avogames account — created once, found on every return, no re-login and no duplicates. That is why the session, handled on both the game's backend and frontend, makes every subsequent game an instant sign-in.
Publisher routing: matchess asks avogames (PLATFORM_SERVER, default https://avogames.com) only when platform=avogames. Steam and the other publishers are still validated against matchess' own global server — the identity always goes back to whichever server actually issued it.
Related articles
Still stuck? Submit a request and include your game's dashboard link.