[NestJS] cors 해결

2024. 2. 24. 23:11·coooding/NestJS

react와 별도로  nestjs를 사용하여 api 서버를 배포 하였더니 cors 문제가 생겨 데이터를 받아오지 못하는 오류가 생겼다.

 

react 서버 도메인은 example.com, api서버 도메인은 api.example.com으로 사용하기에 생긴 문제였다. 이러한 cors 문제는 배포 환경에서는 백엔드에서 해결해야하는 경우가 대부분이다. 

 

첫 시도

자료를 찾아보니 nestjs에서 app.enableCors라는 것을 기본 제공해주어 이것을 사용하여 설정을 하였다.

import { NestFactory } from "@nestjs/core"
import { AppModule } from "./app.module"
import * as cookieParser from "cookie-parser"
import { ValidationPipe } from "@nestjs/common"
import { ConfigService } from "@nestjs/config"

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  app.enableCors({
    origin: ["http://localhost:5173" : "https://example.com/"],
    allowedHeaders: ["Content-Type", "Origin", "X-Requested-With", "Accept", "Authorization"],
    exposedHeaders: ["Authorization"],
    credentials: true
  })

  app.useGlobalPipes(
     new ValidationPipe({
       whitelist: true,
       forbidNonWhitelisted: true,
       transform: true
     })
  )
  app.use(cookieParser())

  await app.listen(5208)
}

bootstrap()

하지만 위의 코드를 적용하여도 해결되는 것은 없었고, 계속하여 다른 방법들을 찾게 되었다.

 

찾아보니 env파일을 이용하여 개발 도메인과 배포 도메인을 분리하는 방법이 있다는 것을 알게되어 두번째 시도를 하였다.

 

두번째 시도

import { NestFactory } from "@nestjs/core"
import { AppModule } from "./app.module"
import * as cookieParser from "cookie-parser"
import { ValidationPipe } from "@nestjs/common"
import { ConfigService } from "@nestjs/config"

async function bootstrap() {
  // 변경된 부분
  const envFile = process.env.NODE_ENV === 'dev' ? "http://localhost:5173" : "https://example.com/"

  const app = await NestFactory.create(AppModule)

  app.enableCors({
    origin: [envFile],
    allowedHeaders: ["Content-Type", "Origin", "X-Requested-With", "Accept", "Authorization"],
    exposedHeaders: ["Authorization"],
    credentials: true
  })

  app.useGlobalPipes(
     new ValidationPipe({
       whitelist: true,
       forbidNonWhitelisted: true,
       transform: true
     })
  )
  app.use(cookieParser())

  await app.listen(5208)
}

bootstrap()

이렇게 시도를 하여도 작동이 잘 되지 않았다. 그래서 삽질을 하던 중, origin: [envFile] 이 부분에서 대괄호를 해제하니 개발 환경에서는 cors가 문제없이 잘 작동하였다.

origin: envFile

 

하지만 여전히 배포 환경에서는 잘 작동하지 않았다. 혹시나 해서 process.env.NODE_ENV를 출력해 보니 undefined가 뜨고 있었다. app.module.ts에서는 잘 출력이 되었지만, main.ts에서는 출력이 되지 않았다. 확인해 보니 env파일이 설정되는 순서 때문에 main.ts에서는 undefined가 출력되었다.

 

이것을 해결하기 위해 env와 관련된 추가적인 라이브러리를 설치하는 것을 많은 사람들이 추천하고 있었는데 추가로 설치하지 않아도 해결할 수 있는 방법이 있을 것 같았다. 일단 main.ts에서 process.env를 출력해보니 NODE_ENV를 제외하고도 많은 값들이 출력되었다. 나는 개발은 윈도우 환경에서, 배포는 ubuntu에서 하기 때문에 이 둘을 명확히 구분할 수 있는 값을 설정하면 될 것이라 생각하였다. 찾아보니 윈도우와 ubuntu를 구분할 수 있는 많은 값들을 확인할 수 있었고, 나는 그 중 process.env.EDITOR 라는 값과 process.env.npm_lifecycle_event라는 값들 중 하나를 사용하기로 했다.

process.env.EDITOR: 'C:\\Windows\\notepad.exe'
process.env.npm_lifecycle_event: 'start:dev'

 

process.env.npm_lifecycle_event라는 값은 ubuntu 환경에서도 사용할 수 있는 명령어라고 생각을 하여 process.env.EDITOR 값을 이용하여 설정을 진행하였다.

import { NestFactory } from "@nestjs/core"
import { AppModule } from "./app.module"
import * as cookieParser from "cookie-parser"
import { ValidationPipe } from "@nestjs/common"
import { ConfigService } from "@nestjs/config"

async function bootstrap() {
  const envFile = process.env.EDITOR === "C:\\Windows\\notepad.exe" ? "http://localhost:5173" : "https://example.com/"

  const app = await NestFactory.create(AppModule)

  app.enableCors({
    origin: envFile,
    allowedHeaders: ["Content-Type", "Origin", "X-Requested-With", "Accept", "Authorization"],
    exposedHeaders: ["Authorization"],
    credentials: true
  })

  app.useGlobalPipes(
     new ValidationPipe({
       whitelist: true,
       forbidNonWhitelisted: true,
       transform: true
     })
  )
  app.use(cookieParser())

  await app.listen(5208)
}

bootstrap()

해당 코드로 작성을 하여도 정상적으로 작동이 되지 않았다. 하지만 envFile값을 출력해보면 값은 정상적으로 들어간 것을 확인할 수 있었다. 그래서 도대체 뭐가 문제일까 하고 확인해보니 배포 도메인 뒤에 붙어있는 / 가 눈에 보였다. 그래서 그 값을 지우고 실행을 해보니 개발 환경, 배포 환경에서 모두 정상 작동하는 것을 확인하였다!

 

아래는 정상작동하는 main.ts 코드다.

import { NestFactory } from "@nestjs/core"
import { AppModule } from "./app.module"
import * as cookieParser from "cookie-parser"
import { ValidationPipe } from "@nestjs/common"
import { ConfigService } from "@nestjs/config"

async function bootstrap() {
  const envFile = process.env.EDITOR === "C:\\Windows\\notepad.exe" ? "http://localhost:5173" : "https://example.com"

  const app = await NestFactory.create(AppModule)

  app.enableCors({
    origin: envFile,
    allowedHeaders: ["Content-Type", "Origin", "X-Requested-With", "Accept", "Authorization"],
    exposedHeaders: ["Authorization"],
    credentials: true
  })

  app.useGlobalPipes(
     new ValidationPipe({
       whitelist: true,
       forbidNonWhitelisted: true,
       transform: true
     })
  )
  app.use(cookieParser())

  await app.listen(5208)
}

bootstrap()

깃허브 주소

https://github.com/Anhye0n/

 

Anhye0n - Overview

anhye0n.me. Anhye0n has 10 repositories available. Follow their code on GitHub.

github.com

 

저작자표시 (새창열림)

'coooding > NestJS' 카테고리의 다른 글

[JWT] Vue, NestJS, jwt를 이용하여 로그인하기 (로그인 구현)  (0) 2023.12.29
'coooding/NestJS' 카테고리의 다른 글
  • [JWT] Vue, NestJS, jwt를 이용하여 로그인하기 (로그인 구현)
stableh
stableh
  • stableh
    생각 정리
    stableh
  • 전체
    오늘
    어제
    • 전체보기 (29)
      • coooding (12)
        • Spring (0)
        • 서버 (3)
        • Java (0)
        • Git (0)
        • Node.js (5)
        • React (1)
        • Javascript (1)
        • NestJS (2)
      • 프로젝트 (1)
        • 개인 블로그 (1)
        • tutorial-sejong (0)
        • Todone (0)
        • Markan (0)
      • 기록 (5)
        • 그냥저냥 (2)
        • 군대 (2)
        • 창업일지 (1)
      • 독서 (0)
        • 개발 서적 (0)
      • 지난 이야기 (11)
  • 블로그 메뉴

    • 홈
    • 블로그 관리
  • 링크

    • Github
    • 관리자페이지
  • 공지사항

  • 인기 글

  • 태그

    MariaDB
    ubuntu 22.04
    JWT
    react-beautiful-dnd
    vue
    React
    노드
    pinia
    상태 관리
    우분투 22.04
    datetime
    err
    favicon
    multer
    EJS
    CORS
    db 이동
    db 복사
    NestJS
    node
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
stableh
[NestJS] cors 해결
상단으로

티스토리툴바