[MSA] Spring Cloud Gateway (1) : CORS + Routing 설정

진예·2024년 8월 1일
0

Backend : Spring

목록 보기
5/8
post-thumbnail
post-custom-banner

➕ API Gateway

MSA 환경 내의 모든 서비스 엔드 포인트 단일화

최근 진행했던 팀 프로젝트의 서비스아키텍처에서 가져온 부분인데, 간단히 설명하자면 프론트 서버에서 API를 호출하면 해당 서비스에 직접 API를 요청하는 것이 아니라, 게이트웨이 서버로 요청을 보낸 후에 게이트웨이에서 라우팅 작업을 통해 해당 서비스로 요청을 전달하는 방식으로 동작하게 된다.

게이트웨이를 사용하지 않으면 프론트에서 각 서버의 url을 알아야 하는데, 게이트웨이 통해 게이트웨이 url만을 사용하여 API 요청이 가능해진다!


💡 Spring Cloud Gateway

Spring Framework에서 제공하는 오픈 소스 기반의 Gateway 서비스

  • Spring Cloud Gateway vs Spring Cloud Zuul (패치 중단)

    SCGZuul
    기반 웹 서버NettyTomcat
    동기/비동기비동기동기
    웹 프레임워크Spring WebfluxSpring Web MVC

✅ 역할

  • Routing : 요청을 전달할 경로(서비스) 설정
  • Load Balancing : 여러 서버에 대한 트래픽을 분배하여 부하 분산 처리
  • Filter : 요청에 대한 특정 작업 수행 → 인증, 에러 처리 등

1. 기본 설정

게이트웨이 서비스 생성 + 유레카 서버에 등록

  • application.yml
server:
  port: 8000

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: gateway


2. CORS 설정

✅ CORS (Cross-Origin Resource Sharing) : 다른 출처에 있는 리소스에 접근(요청)

클라이언트 측에서 서버 측으로 요청을 보내는 경우 출처가 다르므로 접근을 허용하지 않는 경우를 방지하기 위해, 특정 출처를 가지는 클라이언트의 요청의 접근을 허용하도록 설정해야 함!

➕ 모놀리식 아키텍처의 경우 Spring Security를 통해 설정 가능함. MSA 환경에서도 각 서비스 별로 설정 가능하지만, 모든 서비스에 Spring Security 의존성을 추가하고 Config를 작성해줘야 함.. 어차피 게이트웨이를 거쳐서 서비스에 갈 것이기 때문에 게이트웨이에서 CORS에 대한 설정을 해줌으로써 모든 서비스에 공통적으로 적용할 수 있음!

근데 또 공통적인 부분 말고 각 서비스 별로 추가로 설정해줘야 하는 경우가 있을지도?.. 이건 아직 경험 안해봐서 모르겠음 ㅎ..

  • application.yml

    • allowedOrigins : *모든 경로를 허용하지만, allow-credentials: true인 경우에는 *를 사용할 수 없으므로 허용할 모든 출처를 직접 명시해야 함. (ex - JWT 토큰 검증)
spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          "[/**]":
            allowedOrigins: # 허용할 출처(도메인)
              - "http://localhost:3000" # 클라이언트 : 프론트 서버
            allow-credentials: true # 인증 포함 요청 가능 (JWT 토큰)
            allowedHeaders: "*" # 허용할 
            allowedMethods: # 허용할 HTTP 메서드
              - PUT
              - GET
              - POST
              - DELETE
              - OPTIONS # Preflight 요청 시 사용

3. 라우팅 설정

요청 경로에 따라 요청을 전달할 서비스 및 서버 선택 (로드 밸런싱)

  • application.yml

    • uri : 요청을 전달할 주소 → 로드 밸런싱 적용 시 lb://eureka에 등록된 서비스명 형태로 명시

    • predicates : 해당 조건을 만족하는 요청만 명시된 uri로 전달 (조건문)

      • Path : 특정 경로 (ex - /member-service/** 경로의 요청만 전달)
      • Method : 특정 메서드
    • filters : 요청에 특정 작업 수행

      • StripPrefix=n : n번째 경로까지 제거한 후 전달 (ex - /member-service/partners/profile → `/partners/profile)

      • 커스텀 필터도 등록 가능 (ex - JWT 토큰 검증 필터)

spring:
    gateway:
      routes:
        - id: member-service # 라우팅 id
          uri: lb://MEMBER-SERVICE # 이동할 주소
          predicates: # 라우팅 조건 : 경로, 메서드, ...
            - Path=/member-service/**
          filters:
            - StripPrefix=1 # 첫번째 경로 제거
            # - rewritePath=/member-service/(?<segment>.*), /$\{segment} : StripPrefix와 같은 역할

ex1) member-service에 직접 요청

ex2) 게이트웨이를 통한 요청

: 서비스에 직접 요청했을 때와 결과가 같음. 즉, 게이트웨이에서 member-service로 요청을 잘 전달했다는 뜻!

게이트웨이 요청member-service를 붙이지 않으면 404 에러가 발생하는데, 이는 라우팅 설정 시 /member-service/**에 해당하는 요청만 전달하도록 해놔서 그런거임.. 쉽게 말하면 /partners/profile을 처리하는 라우팅이 없기 때문!


🙏🏻 참고

profile
백엔드 개발자👩🏻‍💻가 되고 싶다
post-custom-banner

0개의 댓글