Authentication
Authentication
Realtime SDK uses JWT tokens to authenticate WebSocket connections. Your server generates tokens, and clients pass them when connecting.
How It Works
- Client requests a token from your API
- Your API verifies the user and generates a JWT
- Client passes the token to
RealtimeProvider - Realtime server validates the token before accepting the connection
Server Setup
Generate Tokens
Generate tokens in your API using a JWT library (for example jose):
// api/realtime-token.ts
import { SignJWT } from 'jose';
export async function POST(request: Request) {
// Verify the user is authenticated (your auth system)
const user = await getAuthenticatedUser(request);
if (!user) {
return new Response('Unauthorized', { status: 401 });
}
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
const token = await new SignJWT({
permissions: {
rooms: ['document-*'],
},
})
.setProtectedHeader({ alg: 'HS256' })
.setSubject(user.id)
.setIssuedAt()
.setExpirationTime('1h')
.sign(secret);
return Response.json({ token });
}
Token Claims
The JWT includes these claims:
| Claim | Description |
|---|---|
sub | User ID (required) |
exp | Expiration time (required) |
iat | Issued at time |
permissions | Optional room access control metadata |
Client Setup
Pass the token to RealtimeProvider:
<RealtimeProvider
endpoint="wss://api.realtimesdk.dev"
authToken={async () => {
const res = await fetch('/api/realtime-token', {
method: 'POST',
credentials: 'include', // Include cookies for session auth
});
const { token } = await res.json();
return token;
}}
>
{children}
</RealtimeProvider>
The authToken can be:
- A string (static token)
- A function returning a string
- An async function returning a
Promise<string>
Token Refresh
Tokens expire. The SDK automatically handles reconnection, but you should refresh tokens before expiry:
const authToken = async () => {
// Check if cached token is still valid
const cached = tokenCache.get();
if (cached && !isExpired(cached)) {
return cached;
}
// Fetch a new token
const res = await fetch('/api/realtime-token', { method: 'POST' });
const { token } = await res.json();
tokenCache.set(token);
return token;
};
Self-Hosting
When self-hosting, configure JWT verification in the server:
# Environment variables
TEST_JWT_SECRET=your-secret-key
JWT_ISSUER=your-app (optional)
JWT_AUDIENCE=realtime-sdk (optional)
Generate tokens with the same secret:
import jwt from 'jsonwebtoken';
const token = jwt.sign(
{ sub: userId },
process.env.TEST_JWT_SECRET,
{ expiresIn: '1h' }
);