> ## Documentation Index
> Fetch the complete documentation index at: https://docs-ts.playservices.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# JWT Authentication

> Player token validation, authentication flows, and session management for secure game access

# JWT Authentication

The JWT Authentication system enables secure player access to tournament games through cryptographically signed tokens. Game Platform validates these tokens to authenticate players and authorize their participation in tournaments.

## JWT Token Overview

JWT tokens are issued by the Tournament System when players register for tournaments and contain all necessary information for game platform authentication and authorization.

### Token Structure

JWT tokens follow the standard format: `header.payload.signature`

**Example Token:**

```
eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJ0b3VybmFtZW50SWQiOiIxMjM0NSIsInBsYXllcklkIjoidHBfcGxheWVyXzQ1NiIsInJvb21JZCI6InJvb21fYWJjMTIzIiwiZ2FtZVNsdWciOiJjcmFzaC1jbGFzc2ljIiwicGVybWlzc2lvbnMiOlsicGxheSIsInJlYnV5Il0sImlhdCI6MTY0MjA4OTAwMCwiZXhwIjoxNjQyMDkyNjAwfQ.signature
```

### Token Payload

```json theme={null}
{
  "tournamentId": "12345",
  "playerId": "tp_player_456",
  "roomId": "room_abc123",
  "gameSlug": "crash-classic",
  "permissions": ["play", "rebuy", "chat"],
  "operatorId": "op_1234567890abcdef",
  "playerInfo": {
    "displayName": "PlayerName",
    "entryCount": 2,
    "totalPaid": 20.00,
    "vipLevel": "gold"
  },
  "iat": 1642089000,
  "exp": 1642092600
}
```

### Token Claims

| Claim          | Type   | Description                                           |
| -------------- | ------ | ----------------------------------------------------- |
| `tournamentId` | String | Tournament identifier                                 |
| `playerId`     | String | Tournament-specific player ID                         |
| `roomId`       | String | Game room identifier                                  |
| `gameSlug`     | String | Game type identifier                                  |
| `permissions`  | Array  | Allowed actions (`play`, `rebuy`, `chat`, `spectate`) |
| `operatorId`   | String | Operator identifier for multi-tenant isolation        |
| `playerInfo`   | Object | Player metadata and statistics                        |
| `iat`          | Number | Token issued at timestamp                             |
| `exp`          | Number | Token expiration timestamp                            |

## Token Validation API

### Validate JWT Token

Validate player JWT tokens for game access authorization:

```http theme={null}
POST /internal/auth/validate-token
Authorization: Bearer {internal-api-key}
Content-Type: application/json

{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9..."
}
```

**Response (Valid Token):**

```json theme={null}
{
  "valid": true,
  "tournamentId": "12345",
  "playerId": "tp_player_456",
  "roomId": "room_abc123",
  "gameSlug": "crash-classic",
  "permissions": ["play", "rebuy", "chat"],
  "operatorId": "op_1234567890abcdef",
  "playerInfo": {
    "displayName": "PlayerName",
    "entryCount": 2,
    "totalPaid": 20.00,
    "currentPosition": 15,
    "points": 1250,
    "status": "active",
    "vipLevel": "gold",
    "preferredLanguage": "en"
  },
  "tournamentInfo": {
    "name": "Daily Championship",
    "status": "in_progress",
    "currentRound": 3,
    "totalRounds": 5,
    "startTime": "2024-01-15T20:00:00Z"
  },
  "expiresAt": "2024-01-15T21:30:00Z",
  "remainingTime": 3420
}
```

**Response (Invalid Token):**

```json theme={null}
{
  "valid": false,
  "error": "token_expired",
  "message": "JWT token has expired",
  "expiredAt": "2024-01-15T21:30:00Z"
}
```

### Token Validation Errors

| Error Code                 | Description                       | Action Required                       |
| -------------------------- | --------------------------------- | ------------------------------------- |
| `token_expired`            | Token past expiration time        | Request new token from Casino System  |
| `token_malformed`          | Invalid token format              | Check token format and encoding       |
| `signature_invalid`        | Cryptographic signature failed    | Token may be tampered - reject access |
| `tournament_not_found`     | Tournament doesn't exist          | Verify tournament is still active     |
| `player_eliminated`        | Player eliminated from tournament | Allow spectate mode only              |
| `insufficient_permissions` | Token lacks required permissions  | Check permission requirements         |

## Authentication Flow

### Player Connection Process

```mermaid theme={null}
sequenceDiagram
    participant Player as Player Browser
    participant GamePlatform as Game Platform
    participant TournamentSystem as Tournament System
    participant Casino as Casino System

    Note over Player,Casino: 1. Player Registration (External API)
    Player->>Casino: Register for tournament
    Casino->>TournamentSystem: POST /api/tournaments/{id}/players
    TournamentSystem->>TournamentSystem: Generate JWT token
    TournamentSystem->>Casino: Return JWT + game URL
    Casino->>Player: Redirect to game URL with JWT

    Note over Player,Casino: 2. Game Platform Authentication (Internal API)
    Player->>GamePlatform: Connect to game with JWT token
    GamePlatform->>TournamentSystem: POST /internal/auth/validate-token
    TournamentSystem->>TournamentSystem: Validate signature & expiration
    TournamentSystem->>TournamentSystem: Check tournament & player status
    TournamentSystem->>GamePlatform: Return validation result + player info
    
    alt Token Valid
        GamePlatform->>GamePlatform: Connect player to tournament room
        GamePlatform->>Player: Game connection established
    else Token Invalid
        GamePlatform->>Player: Authentication failed - redirect to casino
    end
```

### Implementation Examples

#### JavaScript Token Validation

```javascript theme={null}
class TournamentAuth {
  constructor(internalApiKey) {
    this.apiKey = internalApiKey;
    this.baseUrl = 'https://tournament-system.internal';
  }
  
  async validateToken(jwtToken) {
    try {
      const response = await fetch(`${this.baseUrl}/internal/auth/validate-token`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${this.apiKey}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ token: jwtToken })
      });
      
      if (!response.ok) {
        throw new Error(`Validation failed: ${response.status}`);
      }
      
      const result = await response.json();
      
      if (!result.valid) {
        console.warn('Token validation failed:', result.error);
        return null;
      }
      
      return {
        tournamentId: result.tournamentId,
        playerId: result.playerId,
        roomId: result.roomId,
        permissions: result.permissions,
        playerInfo: result.playerInfo,
        expiresAt: new Date(result.expiresAt)
      };
      
    } catch (error) {
      console.error('Token validation error:', error);
      return null;
    }
  }
  
  async authenticatePlayer(jwtToken) {
    const validation = await this.validateToken(jwtToken);
    
    if (!validation) {
      throw new Error('Authentication failed - invalid token');
    }
    
    // Check if player has required permissions
    if (!validation.permissions.includes('play')) {
      throw new Error('Authentication failed - insufficient permissions');
    }
    
    // Check token expiration
    if (validation.expiresAt <= new Date()) {
      throw new Error('Authentication failed - token expired');
    }
    
    console.log(`Player ${validation.playerInfo.displayName} authenticated for tournament ${validation.tournamentId}`);
    
    return validation;
  }
}

// Usage example
const auth = new TournamentAuth('internal-api-key');

// Authenticate player on connection
const authenticatePlayerConnection = async (jwtToken) => {
  try {
    const playerAuth = await auth.authenticatePlayer(jwtToken);
    
    // Player authenticated successfully
    return {
      success: true,
      playerId: playerAuth.playerId,
      tournamentId: playerAuth.tournamentId,
      roomId: playerAuth.roomId,
      playerInfo: playerAuth.playerInfo,
      permissions: playerAuth.permissions
    };
    
  } catch (error) {
    console.error('Player authentication failed:', error.message);
    
    return {
      success: false,
      error: error.message
    };
  }
};
```

#### Node.js Middleware Example

```javascript theme={null}
// Express.js middleware for JWT authentication
const authenticatePlayer = async (req, res, next) => {
  try {
    // Extract JWT from Authorization header or query parameter
    const token = req.headers.authorization?.replace('Bearer ', '') || req.query.token;
    
    if (!token) {
      return res.status(401).json({
        error: 'missing_token',
        message: 'JWT token is required'
      });
    }
    
    // Validate token with Tournament System
    const validation = await auth.validateToken(token);
    
    if (!validation) {
      return res.status(401).json({
        error: 'invalid_token',
        message: 'JWT token validation failed'
      });
    }
    
    // Add player info to request object
    req.player = {
      tournamentId: validation.tournamentId,
      playerId: validation.playerId,
      roomId: validation.roomId,
      permissions: validation.permissions,
      info: validation.playerInfo
    };
    
    // Check tournament-specific permissions
    if (req.path.includes('/rebuy') && !validation.permissions.includes('rebuy')) {
      return res.status(403).json({
        error: 'insufficient_permissions',
        message: 'Rebuy permission required'
      });
    }
    
    next();
    
  } catch (error) {
    console.error('Authentication middleware error:', error);
    
    return res.status(500).json({
      error: 'authentication_error',
      message: 'Authentication system error'
    });
  }
};

// Usage in routes
app.get('/game/tournament/:id/join', authenticatePlayer, (req, res) => {
  // Player is authenticated, req.player contains player info
  const { tournamentId, playerId, roomId } = req.player;
  
  res.json({
    message: 'Game joined successfully',
    tournamentId: tournamentId,
    playerId: playerId,
    roomId: roomId
  });
});
```

## Token Refresh & Expiration

### Token Expiration Handling

JWT tokens have limited validity periods. Handle expiration gracefully:

```javascript theme={null}
class TokenManager {
  constructor(auth) {
    this.auth = auth;
    this.tokenCache = new Map();
    this.refreshThreshold = 5 * 60 * 1000; // 5 minutes before expiration
  }
  
  async getValidToken(playerId, currentToken) {
    const cached = this.tokenCache.get(playerId);
    
    // Check if cached token is still valid
    if (cached && cached.expiresAt > new Date(Date.now() + this.refreshThreshold)) {
      return cached.token;
    }
    
    // Validate current token
    const validation = await this.auth.validateToken(currentToken);
    
    if (validation && validation.expiresAt > new Date(Date.now() + this.refreshThreshold)) {
      // Token is still valid, cache it
      this.tokenCache.set(playerId, {
        token: currentToken,
        expiresAt: validation.expiresAt
      });
      
      return currentToken;
    }
    
    // Token expired or expiring soon - request refresh
    return await this.requestTokenRefresh(playerId);
  }
  
  async requestTokenRefresh(playerId) {
    try {
      // Request new token from Casino System
      // This would typically involve redirecting player back to casino
      // or making an API call if refresh tokens are supported
      
      console.log(`Token refresh required for player ${playerId}`);
      
      // For now, indicate token refresh needed
      throw new Error('TOKEN_REFRESH_REQUIRED');
      
    } catch (error) {
      console.error('Token refresh failed:', error);
      throw error;
    }
  }
}
```

### Automatic Token Validation

```javascript theme={null}
// WebSocket connection with automatic token validation
class TournamentSocket {
  constructor(wsUrl, jwtToken) {
    this.wsUrl = wsUrl;
    this.jwtToken = jwtToken;
    this.auth = new TournamentAuth('internal-api-key');
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
  }
  
  async connect() {
    try {
      // Validate token before connecting
      const validation = await this.auth.validateToken(this.jwtToken);
      
      if (!validation) {
        throw new Error('Invalid JWT token');
      }
      
      // Connect to WebSocket with validated token
      this.ws = new WebSocket(`${this.wsUrl}?token=${this.jwtToken}`);
      
      this.ws.onopen = () => {
        console.log('Tournament WebSocket connected');
        this.reconnectAttempts = 0;
      };
      
      this.ws.onmessage = (event) => {
        this.handleMessage(JSON.parse(event.data));
      };
      
      this.ws.onclose = (event) => {
        console.log('Tournament WebSocket closed:', event.code, event.reason);
        
        // Handle different close codes
        if (event.code === 1008) { // Policy violation (auth failure)
          console.error('Authentication failed - token may be invalid');
          this.handleAuthFailure();
        } else {
          this.attemptReconnect();
        }
      };
      
      this.ws.onerror = (error) => {
        console.error('Tournament WebSocket error:', error);
      };
      
    } catch (error) {
      console.error('Tournament connection failed:', error);
      throw error;
    }
  }
  
  handleAuthFailure() {
    // Redirect back to casino for new token
    window.location.href = '/casino/tournament-login?expired=true';
  }
  
  attemptReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      
      const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
      console.log(`Attempting reconnect in ${delay}ms (attempt ${this.reconnectAttempts})`);
      
      setTimeout(() => {
        this.connect();
      }, delay);
    } else {
      console.error('Max reconnection attempts exceeded');
      this.handleAuthFailure();
    }
  }
}
```

## Security Considerations

### Token Security Best Practices

<CardGroup cols={2}>
  <Card title="Signature Verification" icon="shield-check">
    Always verify JWT signatures using EdDSA algorithm with proper key validation
  </Card>

  <Card title="Expiration Checking" icon="clock">
    Validate token expiration times and reject expired tokens immediately
  </Card>

  <Card title="Permission Validation" icon="lock">
    Check token permissions match required actions before allowing access
  </Card>

  <Card title="Secure Transmission" icon="key">
    Only transmit tokens over HTTPS/WSS encrypted connections
  </Card>
</CardGroup>

### Common Security Issues

<Warning>
  **Never trust client-side token validation** - always validate tokens server-side via the internal API. Client-side validation should only be used for UX improvements.
</Warning>

#### Token Tampering Detection

```javascript theme={null}
// Always validate tokens server-side
const validateClientToken = async (clientToken) => {
  // DON'T do client-side validation only
  // const payload = JSON.parse(atob(clientToken.split('.')[1])); // INSECURE
  
  // DO validate via internal API
  const validation = await auth.validateToken(clientToken);
  
  if (!validation) {
    throw new Error('Token validation failed');
  }
  
  return validation;
};
```

#### Replay Attack Prevention

```javascript theme={null}
// Track token usage to prevent replay attacks
class TokenTracker {
  constructor() {
    this.usedTokens = new Set();
    this.cleanupInterval = setInterval(() => {
      this.cleanup();
    }, 60000); // Cleanup every minute
  }
  
  isTokenUsed(tokenId) {
    return this.usedTokens.has(tokenId);
  }
  
  markTokenUsed(tokenId, expiresAt) {
    this.usedTokens.add({
      id: tokenId,
      expiresAt: expiresAt
    });
  }
  
  cleanup() {
    const now = new Date();
    this.usedTokens = new Set([...this.usedTokens].filter(
      token => token.expiresAt > now
    ));
  }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Room Management" icon="users" href="/game-platform-integration/room-management">
    Learn how to manage game rooms and player sessions after authentication.
  </Card>

  <Card title="Real-time Communication" icon="bolt" href="/game-platform-integration/real-time-communication">
    Implement real-time communication patterns for tournament gameplay.
  </Card>
</CardGroup>
