Skip to content

Commit

Permalink
Merge pull request #306 from boostcampwm2023/BE-WsAuth-#299
Browse files Browse the repository at this point in the history
[BE/#299] 웹소켓 인가 처리
  • Loading branch information
namewhat99 authored Dec 5, 2023
2 parents 0e2a72a + 54fe2f2 commit 497715a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 12 deletions.
10 changes: 10 additions & 0 deletions BE/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions BE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@types/multer-s3": "^3.0.3",
"@types/node": "^20.3.1",
"@types/supertest": "^2.0.12",
"@types/ws": "^8.5.10",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
Expand Down
22 changes: 21 additions & 1 deletion BE/src/chat/chat.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import { ChatEntity } from 'src/entities/chat.entity';
import { ChatDto } from './dto/chat.dto';
import { UserEntity } from 'src/entities/user.entity';
import { FcmHandler, PushMessage } from '../utils/fcmHandler';
import * as jwt from 'jsonwebtoken';
import { ConfigService } from '@nestjs/config';
import { JwtPayload } from 'jsonwebtoken';

export interface ChatRoom {
room_id: number;
}

interface Payload extends JwtPayload {
userId: string;
nickname: string;
}
@Injectable()
export class ChatService {
constructor(
Expand All @@ -21,6 +27,7 @@ export class ChatService {
@InjectRepository(UserEntity)
private userRepository: Repository<UserEntity>,
private fcmHandler: FcmHandler,
private configService: ConfigService,
) {}

async saveMessage(message: ChatDto) {
Expand Down Expand Up @@ -141,4 +148,17 @@ export class ChatService {
);
await this.fcmHandler.sendPush(receiver.user_hash, pushMessage);
}

validateUser(authorization) {
try {
const payload: Payload = jwt.verify(
authorization.split(' ')[1],
this.configService.get('JWT_SECRET'),
) as Payload;
console.log(payload.userId);
return payload.userId;
} catch {
return null;
}
}
}
35 changes: 24 additions & 11 deletions BE/src/chat/chats.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,34 @@ import {
WebSocketGateway,
WebSocketServer,
} from '@nestjs/websockets';
import { Server, Websocket } from 'ws';
import { Server, WebSocket } from 'ws';
import { ChatService } from './chat.service';
import { ChatDto } from './dto/chat.dto';
import { Logger } from '@nestjs/common';

interface ChatWebSocket extends WebSocket {
roomId: number;
userId: string;
}
@WebSocketGateway({
path: 'chats',
})
export class ChatsGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Server;
private rooms = new Map<number, Set<Websocket>>();
private rooms = new Map<number, Set<ChatWebSocket>>();
private readonly logger = new Logger('ChatsGateway');
constructor(private readonly chatService: ChatService) {}
handleConnection(client: Websocket) {
this.logger.debug(`on connnect : ${client}`, 'ChatsGateway');
handleConnection(client: ChatWebSocket, ...args) {
const { authorization } = args[0].headers;
const userId = this.chatService.validateUser(authorization);
if (userId === null) {
client.close(1008, '토큰이 유효하지 않습니다.');
}
client.userId = userId;
this.logger.debug(`[${userId}] on connect`, 'ChatsGateway');
}

handleDisconnect(client: Websocket) {
handleDisconnect(client: ChatWebSocket) {
if (client.roomId) {
const roomId = client.roomId;
const room = this.rooms.get(roomId);
Expand All @@ -34,7 +44,7 @@ export class ChatsGateway implements OnGatewayConnection, OnGatewayDisconnect {
}
}
this.logger.debug(
`on disconnect : ${client}, left rooms : ${Array.from(
`[${client.userId}] on disconnect => left rooms : ${Array.from(
this.rooms.keys(),
)}`,
'ChatsGateway',
Expand All @@ -44,10 +54,10 @@ export class ChatsGateway implements OnGatewayConnection, OnGatewayDisconnect {
@SubscribeMessage('send-message')
async sendMessage(
@MessageBody() message: ChatDto,
@ConnectedSocket() client: Websocket,
@ConnectedSocket() client: ChatWebSocket,
) {
this.logger.debug(
`[send message] room ID: ${message['room_id']} , sender: ${message['sender']}, message: ${message['message']}`,
`[${client.userId}] send message { room ID: ${message['room_id']} , sender: ${message['sender']}, message: ${message['message']} }`,
);
const room = this.rooms.get(message['room_id']);
const sender = message['sender'];
Expand All @@ -66,19 +76,22 @@ export class ChatsGateway implements OnGatewayConnection, OnGatewayDisconnect {
@SubscribeMessage('join-room')
joinRoom(
@MessageBody() message: object,
@ConnectedSocket() client: Websocket,
@ConnectedSocket() client: ChatWebSocket,
) {
const roomId = message['room_id'];
client.roomId = roomId;
if (this.rooms.has(roomId)) this.rooms.get(roomId).add(client);
else this.rooms.set(roomId, new Set([client]));
this.logger.debug(`join room : ${roomId}`, 'ChatsGateway');
this.logger.debug(
`[${client.userId}] join room : ${roomId}`,
'ChatsGateway',
);
}

@SubscribeMessage('leave-room')
leaveRoom(
@MessageBody() message: object,
@ConnectedSocket() client: Websocket,
@ConnectedSocket() client: ChatWebSocket,
) {
const roomId = message['room_id'];
const room = this.rooms.get(roomId);
Expand Down

0 comments on commit 497715a

Please sign in to comment.