picture
  1. CORS 설정

CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)는 HTTP 헤더를 사용하여 각기 다른 출처의 웹 어플리케이션에 접근 권한을 부여하는 것을 뜻합니다.
Origin(출처)도메인 및 스키마, 포트 등을 가리키며, 클라우드타입에서 배포하는 서비스를 사용하는 경우에도 각 프레임워크 및 라이브러리에서 권장하는 CORS 설정을 적용해야 합니다.

예를 들어, 프론트엔드 측 https://frontend.com에서 백엔드 측 https://backend.com에 데이터를 요청하는 경우 CORS를 기반으로 하여 HTTP 요청을 하게 되는데, 적절한 설정이 되어있지 않은 경우 코드상 문제가 없다고 하더라도 HTTP 에러가 발생할 수 있습니다. 더불어 보안 측면에서도 허용되지 않은 출처의 서비스가 악의적인 목적으로 데이터를 요청하고 응답받는 등의 사고가 발생할 수 있기 때문에 CORS 관련 설정을 해주는 것이 좋습니다.

프레임워크별 CORS 적용

Node.js(Express)

  • Express를 통해 구현된 웹 서버의 경우 CORS 설정을 위해서 cors 라는 별도의 npm 패키지 설치가 필요합니다. 적용을 위한 코드의 예시는 다음과 같습니다.

    var express = require('express')
    var cors = require('cors')
    var app = express()
    var corsOptions = {
    origin: 'https://sub.example.app',
    // 이 설정은 https://sub.example.app 인 origin을 허용합니다.
    // 어플리케이션 구성에 맞게 origin 규칙을 적용해주세요.
    optionsSuccessStatus: 200
    }
    app.get('/users/:id', cors(corsOptions), function (req, res, next) {
    res.json({msg: 'https://sub.example.app 규칙인 Origin에 대하여 개방'})
    })
    app.listen(80, function () {
    console.log('80번 포트로 서비스 하는 웹서버에 CORS 적용')
    })
  • 자세한 설정은 다음 링크를 참고해주세요.


Nest.js

  • Nest.js의 경우 app 객체 생성시 CORS 관련 설정을 적용할 수 있습니다.

    const app = await NestFactory.create(AppModule);
    app.enableCors();
    await app.listen(3000);
  • CORS 적용 시 다음과 같이 모듈의 설정에 규칙을 추가할 수 있습니다.

    AppModule.forRoot({
    cors: {
    origin: 'https://sub.example.app',
    // 이 설정은 https://sub.example.app 인 origin을 허용합니다.
    // 어플리케이션 구성에 맞게 origin 규칙을 구체적으로 적용해주세요.
    credentials: true,
    },
    }),
  • 자세한 설정은 다음 링크를 참고해주세요.


Spring Boot

컨트롤러 CORS 적용

  • 어노테이션을 통해 컨트롤러 전체 메서드 혹은 일부 메서드에 한정하여 CORS 설정을 적용할 수 있습니다.

    • 컨트롤러 전체 메서드

      @CrossOrigin(origins = "https://sub.example.app")
      // 이 설정은 https://sub.example.app 인 origin을 허용합니다.
      @RestController
      @RequestMapping("/api/v1/students")
      public class StudentController {
      @Autowired
      private StudentRepository studentRepository;
      @GetMapping
      public List<Student> getAllStudents() {
      return studentRepository.findAll();
      }
      @PostMapping
      public Student createStudent(@RequestBody Student student) {
      try {
      return studentRepository.save(student);
      } catch (Exception e) {
      System.out.println(e.getMessage());
      return null;
      }
      }
      }
    • 특정 메서드

      @RestController
      @RequestMapping("/api/v1/students")
      public class StudentController {
      @Autowired
      private StudentRepository studentRepository;
      @CrossOrigin(origins = "https://sub.example.app")
      // 이 설정은 https://sub.example.app 인 origin을 허용합니다.
      @GetMapping
      public List<Student> getAllStudents() {
      return studentRepository.findAll();
      }
      @PostMapping
      public Student createStudent(@RequestBody Student student) {
      try {
      return studentRepository.save(student);
      } catch (Exception e) {
      System.out.println(e.getMessage());
      return null;
      }
      }
      }

전역적 CORS 적용

  • 전역적으로 CORS 설정을 적용하는 경우 WebMvcConfigurer 객체를 Bean으로 등록하는 config 파일을 생성한 후 다음과 같이 작성합니다.

    @Configuration
    public class CorsConfiguration {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
    registry
    .addMapping("/**")
    .allowedOrigins("https://sub.example.app")
    // 이 설정은 https://sub.example.app 인 origin을 허용합니다.
    ;
    }
    };
    }
    }

Flask

  • Flask를 통해 구현된 웹 서버의 경우 CORS 설정을 위해서 flask-cors 라는 별도의 pip 패키지 설치가 필요합니다. 적용을 위한 코드의 예시는 다음과 같습니다.

    app = Flask(__name__)
    cors = CORS(app, resources={r"/api/*": {"origins": "https://sub.example.app"}})
    # 이 설정은 https://sub.example.app 인 origin을 허용합니다.
    @app.route("/api/users")
    def list_users():
    return "All users have been returned."
  • 자세한 설정은 다음 링크를 참고해주세요.


Django

  • Django를 통해 구현된 웹 서버의 경우 CORS 설정을 위해서 django-cors-headers 라는 별도의 pip 패키지 설치가 필요합니다.

  • CORS 설정으로 허용된 출처라 하더라도 CSRF 공격에 관해 신뢰할 수 있는 출처까지 적용되지는 않기 때문에 별도의 옵션을 추가해주어야 합니다. 특히 클라우드타입에서 배포한 서비스에 대해서 공개된 도메인이 CSRF_TRUSTED_ORIGINS에 등록되지 않은 경우 어드민 페이지에 접근이 되지 않는 등의 문제가 발생할 수 있습니다. 적용을 위한 코드의 예시는 다음과 같습니다.

  • settings.py

    INSTALLED_APPS = [
    ...,
    "corsheaders",
    ...,
    ]
    ...
    MIDDLEWARE = [
    ...,
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...,
    ]
    ...
    # CORS 허용된 출처
    CORS_ALLOWED_ORIGINS = [
    "https://example.app",
    "https://sub.example.app",
    "http://localhost:8080",
    "http://127.0.0.1:9000",
    ]
    ...
    # CSRF 신뢰할 수 있는 출처
    CSRF_TRUSTED_ORIGINS = [
    "https://*.example.app",
    ]
  • 자세한 설정은 다음 링크를 참고해주세요.

참고자료

문서

사용에 문제나 어려움이 있다면 디스코드 채널에서 문의하세요.
디스코드 링크