WebSocket
WebSockets don't have a traditional request/response cycle. You verify the token when the client connects, then store the user data on the socket.
Verify on connection
import { WebSocketGateway, OnGatewayConnection } from '@nestjs/websockets';
import { Socket } from 'socket.io';
import { CognitoJwtVerifier, InjectCognitoJwtVerifier } from '@nestjs-cognito/core';
@WebSocketGateway()
export class MessagesGateway implements OnGatewayConnection {
constructor(
@InjectCognitoJwtVerifier()
private readonly jwtVerifier: CognitoJwtVerifier
) {}
async handleConnection(client: Socket) {
try {
const token = client.handshake.headers.authorization?.replace('Bearer ', '');
if (!token) {
client.disconnect();
return;
}
const payload = await this.jwtVerifier.verify(token);
client.data.user = payload;
} catch (error) {
client.disconnect();
}
}
}
Client:
import { io } from 'socket.io-client';
const socket = io('http://localhost:3000', {
extraHeaders: { authorization: `Bearer ${token}` }
});
From cookies
import { parse } from 'cookie';
@WebSocketGateway({ cors: { origin: 'http://localhost:3000', credentials: true } })
export class MessagesGateway implements OnGatewayConnection {
constructor(
@InjectCognitoJwtVerifier()
private readonly jwtVerifier: CognitoJwtVerifier
) {}
async handleConnection(client: Socket) {
try {
const cookies = parse(client.handshake.headers.cookie || '');
const token = cookies['access_token'];
if (!token) {
client.disconnect();
return;
}
const payload = await this.jwtVerifier.verify(token);
client.data.user = payload;
} catch (error) {
client.disconnect();
}
}
}
Client:
const socket = io('http://localhost:3000', {
withCredentials: true
});
Check groups in handlers
import { SubscribeMessage, MessageBody, ConnectedSocket } from '@nestjs/websockets';
import type { CognitoJwtPayload } from '@nestjs-cognito/core';
@WebSocketGateway()
export class MessagesGateway {
@SubscribeMessage('adminAction')
handleAdminAction(
@MessageBody() data: any,
@ConnectedSocket() client: Socket,
) {
const user: CognitoJwtPayload = client.data.user;
const groups = user['cognito:groups'] || [];
if (!groups.includes('admin')) {
throw new UnauthorizedException('Admin access required');
}
return { success: true };
}
}