[typescript] express 모듈 객체의 타입 확장하기

romini·2024년 5월 20일
post-thumbnail

문제인식

jwt토큰을 확인하고 Request에 유저정보를 추가해서 보내주는 jwt인증 미들웨어를 만드는 중인데 ts에러가 발생했다.

// jwt검증 및 유저정보 가져오기
// 모든 API를 거칠 때 권한을 인증할 수 있도록 한다.
import jwt from 'jsonwebtoken';
import database from '../database';

export const jwtAuth = async (req, res, next) => {
  try {
    const headers = req.headers;
    
    const authorization = headers.Authorization || headers.authorization;
    // Bearer ${token} or undefined

    if (authorization?.includes('Bearer') || authorization?.includes('brearer')) {
      if (typeof authorization === 'string') {
        const bearers = authorization.split(' ');

        if (bearers.length === 2 && typeof bearers[1] === 'string') {
          const accessToken = bearers[1];

          // 토큰 복호화
          const decodedToken = jwt.verify(accessToken, process.env.JWT_KEY);

          // 복호화한 토큰으로 유저 찾기
          const user = await database.user.findUnique({
            where: {
              id: decodedToken.id,
            },
          });

          if (user) {
            req.user = user;
            next(); // 미들웨어를 통과해 다음 단계로 넘어감
          } else {
            next({ status: 404, message: '유저를 찾을 수 없습니다.' });
          }
        }
      } else {
        next({ status: 400, message: 'Token이 잘못되었습니다.' });
      }
    } else {
      next({ status: 400, message: 'Token이 잘못되었습니다.' });
    }
  } catch (err) {
    next({ ...err, status: 403 });
  }
};

문제가 발생한 곳은 아래 부분이다.

if (user) {
  req.user = user;
  next(); // 미들웨어를 통과해 다음 단계로 넘어감
} else {
  next({ status: 404, message: '유저를 찾을 수 없습니다.' });
}

TypeScript가 Request 객체에 user 속성이 존재하지 않는다고 인식하기 때문에 발생한다. 이를 해결하기 위해서는 Express의 Request 객체를 확장하여 user 속성을 포함하는 새로운 타입을 정의 해주어야 한다.

해결 방법

  1. 타입 정의 파일을 생성
import { Request } from "express";

declare global {
  namespace Express {
    interface Request {
      user?: object;
    }
  }
}
  • src/types/express 경로에 아래와 같은 파일 index.d.ts를 만들어 Express.Request 인터페이스를 확장하여 user 속성을 추가한다.
  • 참고로 .d.ts 파일은 TypeScript의 타입 선언 파일로, JavaScript 코드 없이 타입 정보만을 포함한다. 이 파일을 사용하면 기존 JavaScript 라이브러리 또는 다른 TypeScript 파일에 타입 정보를 추가할 수 있다.
  1. tsconfig.json 파일에 설정 추가
{
  "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "typeRoots": ["./src/types", "./node_modules/@types"]
  }
}
  • "typeRoots": ["./src/types", "./node_modules/@types"] 설정을 추가해서 확장 타입 파일의 위치를 설정해준다.

0개의 댓글