NestJS | Configuration 설정(+ JWT error 해결)

> 글 작성 계기

지난번 dotenv를 이용해 환경변수를 세팅하다가 JWT를 만나 좌충우돌한 경험이 있습니다.(🥕 해결 방법 링크)

그래서 다른 방법의 환경변수 설정에 목말라 있었는데 역시나 순탄치 않았기에
다시 한 번 글을 작성해보려 합니다.




> config 모듈로 환경변수 세팅

▶︎ 모듈 설치

터미널에서 npm i config를 통해 모듈을 인스톨해줍니다.

윈도우 환경에서는 npm i -g win-node-env도 추가로 설치하셔야 합니다.



▶︎ 환경변수 내용 작성

Project 폴더의 루트 경로에 config라는 이름의 폴더를 만든 후 그 안에
각각 default.yml, development.yml, production.yml파일을 만들어 줍니다.

JSON 형식의 파일로 만들어도 상관 없으나 저는 YAML 형식을 사용하였습니다.

그리고 각각 용도에 맞추어 내용을 삽입해 줍니다.

띄어쓰기는 Tab을 한 번 입력하시면 됩니다.


default.yml: 기본 설정으로 개발환경과 운영환경 모두에 적용됩니다.

server:
  port: 3000

db:
  type: 'postgres'
  port: 5432
  database: 'Project_name'

jwt:
  expiresIn: 3600

development.yml: 개발환경에서 필요한 내용(default도 자동으로 적용됨)

db:
  host: 'localhost'
  username: 'postgres'
  password: '123abc'
  synchronize: true

jwt:
  secret: 'mysecret123key'

production.yml: 운영환경에서 필요한 내용(default도 자동으로 적용됨)

db:
  synchronize: false

▶︎ 환경변수 적용

아래는 Database에 환경변수를 적용한 예시입니다.

import * as config from 'config';
import { TypeOrmModuleOptions } from "@nestjs/typeorm";

const dbConfig = config.get('db')

export const typeORMConfig: TypeOrmModuleOptions = {
    type: dbConfig.type,
    host: process.env.RDS_HOST || dbConfig.host,
    port: process.env.RDS_PORT || dbConfig.port,
    username: process.env.RDS_USERNAME || dbConfig.username,
    password: process.env.RDS_PASSWORD || dbConfig.password,
    database: process.env.RDS_DATABASE || dbConfig.database,
    entities: [__dirname + '/../**/*.entity.{js, ts}'],
    synchronize: dbConfig.synchronize
}

import * as config from 'config';로 모듈을 가져오고
config.get('환경변수_이름')으로 우선 큰 단위의 환경변수 이름을 지정하여
변수에 담아 놓습니다.

해당 환경변수 하위 항목의 이름을 Dot notation으로 호출합니다.(🥕 공식문서 보기)

process.env.RDS_HOST같은 부분은 RDS에 연결했을 때 그에 맞게 만들어놓은
환경변수를 사용하고, 없으면 config 모듈을 통해 설정해 놓은 환경변수를 사용하도록
||연산자를 이용해 지정한 것으로 이 부분은 헷갈리시면 우선 지우셔도 됩니다.

뭐.. 여기 까지는 순탄했습니다만 이번에도 JWT secret이 난리였습니다.


▶︎ JWT secret TypeError와 해결

const jwtConfig = config.get('jwt')

@Module({
  imports: [
    JwtModule.register({
      secret: process.env.JWT_SECRET || jwtConfig.secret,
      signOptions: { expiresIn: jwtConfig.expiresIn }
    }),
    PassportModule.register({ defaultStrategy: 'jwt' }),
    TypeOrmModule.forFeature([UserRepository]),
  ],
  ...

이 방법이 정석이지만 저의 경우 저대로 작성해 놓으면 jwt secret 부분이 계속해서
TypeError가 발생하였습니다.

jwt strategy의 secretOrKey 부분도 마찬가지였습니다.

이런 경우 다음과 같이 해당 변수 부분을 `${}`으로 감싸주시면 해결됩니다.

secret: `${jwtConfig.secret}`

호호..


dotenv때부터 저를 괴롭히던 부분이었고 지난번에 뭔가 보기도 안좋고 찝찝한
느낌으로 마무리 되었는데 되돌아보니 그래도 나름 다 잘 해결해나간 것 같아
기분이 좋습니다.😃

좋은 웹페이지 즐겨찾기