https://socket.io/how-to/use-with-jwt
공식 문서에 무척 잘 나와있다. 하지만 TypeScript 형식으로 사용하기에 조금 부족한 부분이 있다. 그렇기에 내 프로젝트에 맞게 다시 한번 정리해 보도록 하자.
기존 코드
Mongoose와 연결한 미들웨어
import jwt from 'jsonwebtoken';
import { Socket } from 'socket.io';
import { Request, Response, NextFunction} from "express";
import User from "@models/userModel";
import asyncHandler from "express-async-handler";
import { toObjectHexString } from "@src/configs/toObjectHexString";
const JWT_SECRET = process.env.JWT_SECRET as string;
const decodeJWTMiddleware = asyncHandler(
async (req: Request, res: Response, next: NextFunction) => {
if(req.query.sid !== undefined) // Handshake가 아닌경우
return next();
const authToken = req.headers["authorization"];
if (!authToken)
return next(new Error("no token"));
if (!authToken.startsWith("Bearer "))
return next(new Error("invalid token"));
const token = authToken.substring(7);
console.log("middle!");
try {
const decoded = jwt.verify(token, JWT_SECRET) as { sub: any; };
const pk = decoded.sub
req.user = await User.findById(toObjectHexString(pk)) || undefined;
next();
} catch (error) {
res.status(401);
throw new Error("Not authorized, token failed");
}
}
);
export { decodeJWTMiddleware };
project-root/
│
├── src/
...
...
...
│ ├── sockets/ // Socket.io 관련 로직
│ │ ├── middlewares/ // Express 미들웨어
│ │ │ └── authMiddleware.ts
│ │ ├── handlers/ // Socket.io 이벤트 핸들러
│ │ │ ├── chatHandlers.ts
│ │ │ └── setupHandlers.ts
│ │ └── index.ts // Socket.io 초기화
│ ├── index.ts // 서버 시작점
│ └── app.ts // Express 앱 설정
...
...
제공된 방법
기존 코드 수정
const newSocket = io(process.env.NEXT_PUBLIC_SOCKET_CHAT_URL as string, {
path: "/chat/socket.io/",
extraHeaders: {
authorization: `Bearer ${myToken}`
}
});
사용자 ID의 JWT를 임의 생성해서 Front-End의 socket Header로 추가해 준 뒤, 테스트해 보았다.
미들웨어 코드
JWT 미들웨어가 없을 경우엔, 잘 접근이 되는 모습을 확인할 수 있고

JWT 미들웨어를 추가 시킬 경우엔, 접근이 제한되는 것을 확인할 수 있다.

polling.js:310
GET <http://localhost:4000/chat/socket.io/?EIO=4&transport=polling&t=P2NivbN> 400 (Bad Request)
이후 특정 ID 값의 나타내는 JWT를 Client 요청 추가해주니, JWT 정보를 잘 확인해서 ID 값을 받아오는 것을 확인할 수 있다.
