Steam Auth Tickets
Secure backend authentication via Steam-issued auth tickets. Use this to implement "Sign in with Steam" for multiplayer servers, Supabase, Firebase, Colyseus, or any backend that needs to verify a player's identity.
Why not just use getSteamID()?
getSteamID() returns a display value that any modified client can fake. Auth tickets are cryptographically signed by Steam's servers: your backend verifies them directly with Valve, so a tampered client cannot forge a valid identity.
How it works
- Your game calls
getAuthTicketForWebApi(identity): Steam returns a signed ticket - Your game sends the
ticketHexto your backend (via fetch, WebSocket, etc.) - Your backend calls Steam Web API
ISteamUserAuth/AuthenticateUserTicketwith your publisher key to verify the ticket - Steam confirms the player's Steam ID: your backend can trust it
Methods
getAuthTicketForWebApi(identity?)
Request a Steam auth ticket for web API verification. Blocks briefly while Steam generates the ticket (typically < 1 second).
javascript
const result = await steam.getAuthTicketForWebApi('my-game-server');
// {
// handle: 3,
// ticketHex: "14000000EA27DA2DE6F9B9CDE7DA720001001016...",
// identity: "my-game-server"
// }Parameters:
identity(optional): A string identifying your backend service. Steam includes this in the ticket so your server can verify which service the ticket was intended for. Use a consistent name like"my-game-server"or"production-api".
Returns: { handle, ticketHex, identity }
handle: Ticket handle (used to cancel later).0if the request failed.ticketHex: The ticket as a hex string. Send this to your backend.identity: The identity string you passed in (ornull).
cancelAuthTicket(handle)
Cancel an active auth ticket. Call this when the player logs out or the session ends.
javascript
await steam.cancelAuthTicket(result.handle);TIP
Steam allows a maximum of 10 active auth tickets per user. Always cancel tickets when they're no longer needed.
Examples
Sign in with Steam (fetch)
javascript
async function signInWithSteam() {
// 1. Get auth ticket from Steam
const { handle, ticketHex } = await steam.getAuthTicketForWebApi('my-backend');
if (!handle) {
console.error('Failed to get auth ticket');
return null;
}
// 2. Send ticket to your backend for verification
const response = await fetch('https://api.my-game.com/auth/steam', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ticket: ticketHex })
});
const session = await response.json();
// session.userId, session.token, etc.
// 3. Cancel the ticket (backend already verified it)
await steam.cancelAuthTicket(handle);
return session;
}Backend verification (Node.js example)
javascript
// On your server, NOT in the game client
const STEAM_WEB_API_KEY = process.env.STEAM_WEB_API_KEY;
const APP_ID = '480'; // Your Steam App ID
async function verifySteamTicket(ticketHex) {
const url = `https://api.steampowered.com/ISteamUserAuth/AuthenticateUserTicket/v1/?key=${STEAM_WEB_API_KEY}&appid=${APP_ID}&ticket=${ticketHex}`;
const res = await fetch(url);
const data = await res.json();
if (data.response?.params?.result === 'OK') {
return {
steamId: data.response.params.steamid,
ownerSteamId: data.response.params.ownersteamid,
vacBanned: data.response.params.vacbanned,
publisherBanned: data.response.params.publisherbanned
};
}
throw new Error('Steam ticket verification failed');
}Colyseus / multiplayer server auth
javascript
// Client side (in your GemShell game)
async function joinGameServer() {
const { ticketHex } = await steam.getAuthTicketForWebApi('colyseus');
const steamId = await steam.getSteamID();
const room = await client.joinOrCreate('game-room', {
steamTicket: ticketHex,
steamId: steamId
});
return room;
}javascript
// Server side (Colyseus room)
async onAuth(client, options) {
const verified = await verifySteamTicket(options.steamTicket);
if (verified.steamId !== options.steamId) {
throw new Error('Steam ID mismatch');
}
return { steamId: verified.steamId };
}