# How CloddsBot WebSocket Authentication Works: Token-Based Handshake and Session Management

> Discover how CloddsBot WebSocket authentication functions with token-based handshake and session management. Learn about secure, persistent connections for your bot.

- Repository: [AL/CloddsBot](https://github.com/alsk1992/CloddsBot)
- Tags: internals
- Published: 2026-09-13

---

**CloddsBot authenticates WebSocket connections using a custom `WSClient` class that transmits a token via an `auth` message immediately after the socket opens, validates the server's `authenticated` response, and maintains persistent sessions with automatic reconnection and exponential back-off.**

The `alsk1992/CloddsBot` repository implements a robust client-side authentication protocol for its real-time web chat interface. Unlike standard cookie-based WebSocket upgrades, CloddsBot uses an explicit message-based handshake defined in [`public/webchat/js/ws.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/ws.js) to establish secure, stateful connections that survive network interruptions.

## The WSClient Architecture

At the core of CloddsBot's WebSocket authentication is the **`WSClient`** class located in [`public/webchat/js/ws.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/ws.js). This utility manages the entire connection lifecycle, from initial handshake through reconnection, ensuring the client maintains a valid authenticated session before transmitting chat messages.

The class stores three critical identifiers supplied during connection:

- **`token`** – The authentication credential (typically a JWT or API key)
- **`userId`** – A unique identifier for the client (generated or provided)
- **`sessionId`** – An optional conversation session identifier for resuming specific chats

## Step-by-Step Authentication Flow

### Connection Initiation

Authentication begins when the application calls **`WSClient.connect(token, userId, sessionId)`**. According to the source code in [`public/webchat/js/ws.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/ws.js), this method performs the following operations:

1. Stores the provided credentials in instance variables
2. Tears down any existing socket connection to prevent duplicate sessions
3. Opens a new WebSocket to `ws://…/chat` (or `wss://` when the page loads via HTTPS)

The connection uses protocol detection to ensure encrypted transport when available, falling back to unencrypted WebSocket only when necessary.

### The Authentication Handshake

Once the socket's `onopen` event fires, the client immediately transmits a JSON authentication message:

```javascript
{
  "type": "auth",
  "token": "<provided token>",
  "userId": "<provided userId or generated>",
  "_wsVersion": 4
}

```

This `auth` message is the **only** transmission of the token within the protocol. The server validates the token and responds with a message where `type` equals **`authenticated`**. Upon receiving this confirmation, the client:

- Sets `authenticated = true` internally
- Resets the exponential reconnect back-off timer
- Initiates a periodic **ping** every 25 seconds to keep the connection alive

If the server returns an error (such as `Invalid token`), the `authenticated` event never fires, triggering the error handling logic in [`public/webchat/js/app.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/app.js).

### Session Handling After Authentication

After successful authentication, CloddsBot supports **session switching** to resume specific conversations. If a `sessionId` was provided to `connect()`, the client automatically sends a switch message:

```javascript
{
  "type": "switch",
  "sessionId": "<provided sessionId>"
}

```

The server acknowledges this with a `switched` message type, at which point the UI updates to reflect the active conversation context. This mechanism allows users to reconnect to existing chat sessions without re-authenticating or losing conversation history.

### Reconnection and Re-authentication

The `WSClient` class implements automatic reconnection with exponential back-off when connections drop unexpectedly. Crucially, **the entire authentication sequence repeats on every reconnect**:

1. The client attempts to open a new socket
2. Upon `onopen`, it resends the `auth` message with the original token
3. It waits for the `authenticated` response before marking the connection ready
4. If a session was active, it resends the `switch` message to restore context

This ensures that transient network failures never leave the client in a semi-authenticated state. The token persists in `localStorage` (managed via [`public/webchat/js/storage.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/storage.js)) and is reused across page reloads and reconnections.

## UI Integration and Error Handling

The **`App`** class in [`public/webchat/js/app.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/app.js) orchestrates the UI response to authentication events. It listens for the `authenticated` event to:

- Update the connection status indicator
- Refresh chat history that may have been missed during disconnection
- Enable the message input interface

When authentication fails (e.g., expired or invalid tokens), the UI displays a prompt requesting new credentials, stores the updated token via the storage module, and reloads the page to establish a fresh authenticated session.

## Implementation Examples

### Opening an Authenticated WebSocket Connection

```javascript
import { WSClient } from './ws.js';

const token = Storage.get('webchat_token') || '';
const userId = 'web-' + Date.now();
const ws = new WSClient();

// Connect automatically triggers the auth handshake
ws.connect(token, userId, 'session-123');

```

### Server-Side Authentication Handler

The following Python pseudo-code illustrates how the server processes the CloddsBot auth message:

```python
import json

async def on_message(ws, data):
    msg = json.loads(data)
    
    if msg['type'] == 'auth':
        if validate_token(msg['token']):
            await ws.send(json.dumps({
                'type': 'authenticated'
            }))
            # Associate userId with connection state

        else:
            await ws.send(json.dumps({
                'type': 'error', 
                'message': 'Invalid token'
            }))

```

### Switching Sessions After Authentication

```javascript
// After successful authentication, change conversation context
ws.switchSession('new-session-id');

```

## Summary

- **Token-based handshake**: CloddsBot transmits the `auth` message immediately after WebSocket connection, including the token, userId, and protocol version (`_wsVersion: 4`).
- **File location**: Core logic resides in [`public/webchat/js/ws.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/ws.js) with UI coordination in [`public/webchat/js/app.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/app.js).
- **Automatic recovery**: The client re-authenticates automatically on every reconnect using exponential back-off.
- **Session persistence**: Optional `sessionId` support allows resuming specific conversations via the `switch` message protocol.
- **Keep-alive mechanism**: Authenticated connections send periodic pings every 25 seconds to prevent timeout.

## Frequently Asked Questions

### What happens if the WebSocket authentication token is invalid?

If the server rejects the token, it sends an error message instead of `authenticated`. The `App` class in [`public/webchat/js/app.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/app.js) detects this failure, displays a credential prompt to the user, stores the new token in `localStorage`, and reloads the page to reinitialize the connection with valid credentials.

### How does CloddsBot handle network interruptions during an active chat?

The `WSClient` class automatically initiates reconnection with exponential back-off. Upon reconnection, it re-executes the complete authentication handshake (sending the `auth` message and waiting for `authenticated`) before resuming the session. If a `sessionId` was active, it also resends the `switch` message to restore the conversation context.

### Where is the WebSocket authentication token stored?

The token persists in the browser's `localStorage` under the key `webchat_token`, managed by the `Storage` utility in [`public/webchat/js/storage.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/storage.js). This allows the token to survive page reloads and browser restarts, enabling seamless reconnection without requiring the user to re-enter credentials.

### Can I use the CloddsBot WebSocket client with custom authentication servers?

Yes, provided your server implements the expected message protocol. Your server must handle the `auth` message type, validate the `token` field, and respond with `{"type": "authenticated"}`. For session support, implement handlers for `switch` messages and return `switched` acknowledgments as defined in the [`public/webchat/js/ws.js`](https://github.com/alsk1992/CloddsBot/blob/main/public/webchat/js/ws.js) source.