Skip to main content

Game Authentication

Authenticate users with your game using the Intraverse authentication service.

Overview

The Intraverse authentication service provides a secure way to authenticate users with your game. Instead of implementing your own authentication system, you can redirect users to the Intraverse authentication service and receive authentication data through a custom protocol URL.

Authentication Flow

  1. Generate Authentication Hash: Your game generates a UUID v4 hash
  2. Redirect to Auth Service: Redirect users to https://play.intraverse.io/
  3. User Authentication: Users authenticate through the Intraverse service
  4. Callback Protocol: After successful authentication, the service opens a custom protocol URL with authentication data

Implementation

Step 1: Generate Authentication Hash

Generate a UUID v4 hash that will be used to identify the authentication session:

import { v4 as uuidv4 } from "uuid";

const authHash = uuidv4(); // e.g., "12345678-1234-1234-1234-123456789012"

Step 2: Redirect to Authentication Service

Redirect users to the Intraverse authentication service with your client key and generated hash:

const clientKey = "your-client-key";
const authHash = uuidv4();
const authUrl = `https://play.intraverse.io/magic-login?hash=${authHash}&game=${clientKey}`;

// Redirect user to authentication service
window.location.href = authUrl;
// or for mobile apps: open URL in browser

Step 3: Handle Authentication Callback

After successful authentication, the service will open a custom protocol URL with the authentication data. Your game should register a custom protocol handler to receive this data.

Custom Protocol URL Structure

The authentication service will open a URL with the following structure:

{game.magicLinkProtocol}/callback/{idToken}/{refreshToken}/{userId}

Protocol URL Parameters

ParameterTypeDescription
idTokenstringFirebase ID token containing user authentication data
refreshTokenstringFirebase refresh token for token renewal
userIdstringUser ID from Intraverse

Example Protocol URL

game/callback/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/user-123

Protocol Handler Registration

Desktop Applications

Register your custom protocol in your application:

// Example for Electron
app.setAsDefaultProtocolClient("game");

// Handle protocol activation
app.on("open-url", (event, url) => {
const urlObj = new URL(url);
if (urlObj.protocol === "game:" && urlObj.pathname.startsWith("//callback/")) {
const pathParts = urlObj.pathname.split("/");
const idToken = pathParts[3]; // /callback/idToken/refreshToken/userId
const refreshToken = pathParts[4];
const userId = pathParts[5];

// Handle authentication data
handleAuthentication(idToken, refreshToken, userId);
}
});

Mobile Applications

For mobile apps, register the custom protocol in your app configuration:

iOS (Info.plist)

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.yourgame.auth</string>
<key>CFBundleURLSchemes</key>
<array>
<string>game</string>
</array>
</dict>
</array>

Android (AndroidManifest.xml)

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="game" />
</intent-filter>
</activity>

Unity (All Platforms)

For Unity projects, the Universal Deep Linking package simplifies deep link handling across all supported platforms (iOS, Android, desktop, etc.).

Install the package from the Unity Asset Store: Universal Deep Linking - Asset Store

Step 1: Redirect Users to Intraverse Login

When you want to connect users to their Intraverse account, open the following URL in the user's browser:

https://play.intraverse.io/magic-login?game={your-game-client-key}

Replace {your-game-client-key} with the client key assigned to your game.

After the user authenticates, Intraverse will trigger a deep link back into your game with the following structure:

{magicLinkProtocol}/callback/{idToken}/{refreshToken}/{userId}

For example, if your game's magic link protocol is intraversekarting://kartinggame, the callback URL would look like:

intraversekarting://kartinggame/callback/eyJhbGciOi.../dHlwIjoiSl.../user-abc-123

With the Universal Deep Linking package integrated, your Unity client will receive this URL automatically. Parse it to extract:

  • idToken — JWT token for authenticating API requests
  • refreshToken — token used to renew the idToken when it expires
  • userId — the user's Intraverse ID

Step 3: Call Authenticated APIs

To call user-authenticated Intraverse APIs, pass the idToken in the Authorization header:

Authorization: Bearer {idToken}

For example, you can fetch the user's Intraverse profile to display which account they are logged in with during a tournament.

Step 4: Refresh the Token (Optional)

If you need to revalidate or refresh an expired idToken, use the Google Identity Toolkit API with the googleApiKey provided to you:

string refreshTokenUrl = $"https://securetoken.googleapis.com/v1/token?key={googleApiKey}";

In most cases this is not necessary — fetching the userId once during login is sufficient for typical game integrations.

Security Considerations

  • Hash Expiration: Generated hashes should expire after a reasonable time (e.g., 10 minutes)
  • Token Validation: Always validate the JWT token on your server
  • Protocol Security: Ensure your custom protocol handler validates the hash matches the one you generated
  • HTTPS Only: Always use HTTPS for the authentication service URL

Example Implementation

class IntraverseAuth {
constructor(clientKey) {
this.clientKey = clientKey;
this.pendingAuths = new Map();
}

async authenticate() {
// Generate authentication hash
const authHash = uuidv4();

// Store pending authentication
this.pendingAuths.set(authHash, {
timestamp: Date.now(),
resolved: false,
});

// Redirect to authentication service
const authUrl = `https://play.intraverse.io/magic-login?hash=${authHash}&game=${this.clientKey}`;
window.location.href = authUrl;

// Return promise that resolves when authentication completes
return new Promise((resolve, reject) => {
this.pendingAuths.get(authHash).resolve = resolve;
this.pendingAuths.get(authHash).reject = reject;

// Set timeout for authentication
setTimeout(() => {
if (!this.pendingAuths.get(authHash).resolved) {
this.pendingAuths.delete(authHash);
reject(new Error("Authentication timeout"));
}
}, 600000); // 10 minutes
});
}

handleAuthCallback(url) {
const urlObj = new URL(url);
if (urlObj.protocol === "game:" && urlObj.pathname === "//auth") {
const params = new URLSearchParams(urlObj.search);
const hash = params.get("hash");
const token = params.get("token");
const user = params.get("user");
const expires = params.get("expires");

const pendingAuth = this.pendingAuths.get(hash);
if (pendingAuth && !pendingAuth.resolved) {
pendingAuth.resolved = true;
this.pendingAuths.delete(hash);
pendingAuth.resolve({ token, user, expires });
}
}
}
}

Getting an API Key

  1. Contact our team at hello@intraverse.com
  2. Receive your API key and documentation

Security Best Practices

🔑 API Key Security

  1. Never expose server API keys in client-side code
  2. Use environment variables to store sensitive credentials
  3. Rotate API keys regularly (recommended: every 90 days)
  4. Use different keys for different environments (dev, staging, production)
  5. Monitor API key usage for suspicious activity

🎮 Client Key Security

  1. Client keys are safe to include in client applications
  2. Client keys are public identifiers for your game
  3. Never use client keys for server-only operations
  4. Keep client keys consistent across your game versions

🔐 JWT Token Security

  1. Validate JWT tokens on your server
  2. Check token expiration before using
  3. Never store tokens in insecure storage
  4. Implement proper session management
  5. Log out users when tokens expire

🌐 Network Security

  1. Use HTTPS for all API communications
  2. Validate SSL certificates in production
  3. Implement certificate pinning for mobile apps
  4. Use secure WebSocket connections if applicable

🔍 Authentication Flow Security

  1. Validate authentication hashes match your generated hash
  2. Set appropriate hash expiration times (recommended: 10 minutes)
  3. Implement timeout handling for authentication flows
  4. Log authentication attempts for security monitoring
  5. Handle authentication errors gracefully

📱 Client Application Security

  1. Never store sensitive data in client storage
  2. Use secure communication for all API calls
  3. Implement proper error handling
  4. Validate all user inputs before sending to API
  5. Use secure random generation for authentication hashes

Next Steps