Socket Authentication
How the console socket service authenticates with short-lived socket tokens, and what extension code that subscribes to realtime channels needs to know.
Socket Authentication
The socket service connects the console to the SocketCluster server with a short-lived socket token minted from the console session. This page covers what that means for extension code that subscribes to channels.
What the service does
- Handshake. The service gives the SocketCluster client an in-memory auth engine. Every connect and reconnect asks it for a token: while the user is signed in, the engine calls
POST int/v1/socket/tokenand returns{ token, expires_in, expires_at }. A cached token is reused while it has more than 60 seconds left. Subscriptions made before the handshake are sent after it, so they are authenticated too. The token is never stored inlocalStorageand never added to the socket URL. - Anonymous fallback. With no session, or when the server cannot mint tokens (an older server, or socket auth turned off, which answers
404), the client connects anonymously, as it did before socket auth existed. - Refresh. The service authenticates the open socket with a new token 60 seconds before the current one expires.
- Recovery. If the server drops the token (
deauthenticate), or removes a channel for a token reason (kickOut, orsubscribeFailwith anAuthErrorwhose reason isno_token,token_expired,token_changed,deauthenticatedoridentity_changed), the service gets a fresh token, authenticates, and subscribes to the lost channels again by name. Each channel is retried once per token, and there are at most 3 recoveries a minute. - Session lifecycle. Login and an organization switch re-key the socket with a new token. On restore, an anonymous socket is authenticated once the user has loaded. Logout clears the token, stops the refresh timer and disconnects.
- Client tag. The handshake URL carries
?client=console/<version>. This value is not a secret; the server uses it to label its authorization logs.
What extension authors need to know
Channel names are unchanged. Keep subscribing the way you do now, either with socket.listen(channel, callback) or with socket.instance().subscribe(channel) and a for await loop. You don't need to pass a token or call authenticate yourself.
Subscriptions are authorized on the server. Once a server enforces socket auth, the socket server checks each subscribe against the API. A user can only subscribe to channels for records their organization owns, plus their own user.* and company.* channels. A channel name for another organization's record is refused even if the client knows the id.
A recovered channel keeps delivering to your existing loop. SocketCluster sends a channel's data by name. When the service resubscribes a channel after a token problem, the for await loop you started keeps getting messages, and you don't need to subscribe again.
Handle subscribeFail for channels the user may not see. A refusal for any other reason (the user may not access that record) is not retried, so show it or log it instead of waiting forever:
const channel = this.socket.instance().subscribe(`order.${order.public_id}`);
(async () => {
for await (const { error } of channel.listener('subscribeFail')) {
// error.name === 'AuthError'; error.reason is a short snake_case code
// such as `forbidden` or `unknown_prefix`.
this.notifications.warning(error.message);
}
})();
(async () => {
for await (const output of channel) {
// handle the event
}
})();Close the channel when you are done with it (channel.close(), or socket.closeChannels() for channels opened with listen). Closing also ends the subscribeFail listener loop.
Server-side publishing only. Clients cannot publish, transmit or invoke on the socket once it enforces auth. All realtime events come from the API.
Related
socketservice — methods and a basic example- SocketCluster Broadcasting — publishing events from your extension's backend
- Socket Events — channel reference and authorization rules
- System Setup → Socket — authentication modes and self-hosting configuration
Ember Services
Reference for the host services your extension consumes — fetch, store, current-user, session, abilities, intl, notifications, socket, crud, chat, theme, modalsManager, events, app-cache, language, hostRouter, and more.
API Services
Backend support classes shipped by fleetbase/core-api — SmsService, the Support\Http and Support\Find/Resolve helpers, NotificationRegistry, and the SocketCluster broadcaster.