# User Authentication

User authentication signs in a WebSocket connection as an application user. It is separate from private or presence channel authorization.

Call `pusher.signin()` after connecting. A successful sign-in enables:

- Server-to-user events.
- Watchlist online/offline events.
- Terminating all active connections for a `user_id`.

## Client setup

```js
const pusher = new Pusher('app_key', {
    wsHost: 'wss.vask.dev',
    wsPort: 443,
    forceTLS: true,
    enabledTransports: ['ws', 'wss'],
    userAuthentication: {
        endpoint: '/pusher/user-auth',
    },
});

pusher.signin();
```

On sign-in, the SDK calls your `userAuthentication.endpoint` with the connection `socket_id`.

## Server response

Your endpoint returns `auth` and `user_data`. The `user_data` value must be a JSON-encoded string and must include a non-empty `id`.

```json
{
    "auth": "app_key:hmac_signature",
    "user_data": "{\"id\":\"user-123\",\"name\":\"Ada\"}"
}
```

The signature covers:

```text
{socket_id}::user::{user_data}
```

## WebSocket frame

The SDK sends this frame after it receives your auth response:

```json
{
    "event": "pusher:signin",
    "data": {
        "auth": "app_key:hmac_signature",
        "user_data": "{\"id\":\"user-123\",\"name\":\"Ada\"}"
    }
}
```

Vask replies with:

```json
{
    "event": "pusher:signin_success",
    "data": {
        "user_data": "{\"id\":\"user-123\",\"name\":\"Ada\"}"
    }
}
```

If the signature is invalid, the client receives `pusher:error`.

## Adding a watchlist

Add `watchlist` to `user_data` when the signed-in user should receive online/offline events for a set of other users.

```json
{
    "id": "user-123",
    "name": "Ada",
    "watchlist": ["user-456", "user-789"]
}
```

Bind watchlist events after sign-in.

```js
pusher.signin();

pusher.user.watchlist.bind('online', (event) => {
    console.log(event.user_ids);
});

pusher.user.watchlist.bind('offline', (event) => {
    console.log(event.user_ids);
});
```

## Presence is not user sign-in

Presence channel `user_id` identifies a member inside that channel. User authentication identifies the whole connection.

Use `pusher:signin` if you need server-to-user events or user termination. A client that only joins a presence channel is not enough for those features.

## Related docs

- [Watchlist events](/docs/watchlist-events)
- [User connections](/docs/user-connections)
- [Authentication and signatures](/docs/authentication)
