스프링 클라우드 게이트웨이를 이용하여 만들었던 단일 서버 분리 필요
Eureka를 사용하여 Spring Cloud Gateway와 MODULE_COMMON 인스턴스를 이용하여 인증/ 인가 부분을 분리한다.
SpringBoot 3.3.2 + JPA + Spring Security
[apigateway 폴더 구조]
1. apigateway → [build.gradle]
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.projectlombok:lombok:1.18.34'
//Jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
..
2. apigateway → [application.yml]
server:
port: 9000
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka
spring:
jwt:
secret: {secretKey}
main:
web-application-type: reactive
application:
name: apigateway-server
cloud:
gateway:
routes:
- id: module-common
uri: lb://MODULE-COMMON
predicates:
- Path=/module-common/auth/signup
- Method=POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/module-common/(?<segment>.*), /$\{segment}
- id: module-common
uri: lb://MODULE-COMMON
predicates:
- Path=/module-common/auth/login
- Method=POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/module-common/(?<segment>.*), /$\{segment}
- uri: lb://MODULE-COMMON
→ MODULE-COMMON이라는 서비스 디스커버리(예: Eureka)에 등록된 마이크로서비스로 요청을 라우팅한다.
- module-common 회원가입 요청 url = http://localhost:9001/auth/signup
→ apigateway의 포트인 9000으로 /module-common/auth/signup으로 POST 요청시 RewritePath 필터를 사용하여 요청 경로(URL)를 재작성한다.
RewritePath
: Spring Cloud Gateway의 필터 중 하나로, 요청 경로를 재작성합니다. 이 필터는 특정 패턴과 일치하는 경로를 찾아서, 다른 형식으로 변환하여 백엔드 서비스에 전달합니다.
/common-module/(?<segment>.*):/common-module로 시작하는 요청 경로를 대상으로 합니다.(?<segment>.*)는 정규 표현식(regular expression)으로, 모든 문자를 포함한 경로 부분을 캡처하여 **segment**라는 이름으로 저장합니다.
처리: RewritePath 필터가 '/module-common/'를 제거하고, 나머지 부분을 새로운 경로로 사용합니다.
왜 Cookie 헤더를 제거할까?
- 보안 강화:
- 민감한 정보 보호: Cookie에는 종종 세션 토큰이나 사용자 인증 정보가 포함됩니다. 이러한 정보를 백엔드 서비스로 전달하지 않음으로써 보안 위협을 줄일 수 있습니다.
- 크로스 사이트 요청 위조 (CSRF) 방지: 일부 공격 시나리오에서 Cookie를 이용한 CSRF 공격을 방지하기 위해 Cookie 헤더를 제거할 수 있습니다.
- 프라이버시 보호:
- 개인 정보 최소화: 사용자에 대한 불필요한 개인 정보를 백엔드 서비스로 전달하지 않음으로써 프라이버시를 보호할 수 있습니다.
- 백엔드 서비스 간의 독립성 유지:
- 서비스 분리: 각 마이크로서비스가 독립적으로 동작하도록 하고, 불필요한 정보가 서비스 간에 공유되지 않도록 할 수 있습니다.
- 트래픽 최적화:
- 헤더 크기 감소: 불필요한 헤더를 제거하여 네트워크 트래픽을 줄이고, 응답 속도를 향상시킬 수 있습니다.
3. apigateway → [SecurityConfig]
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.csrf(csrf -> csrf.disable());
return http.build();
}
}
왜 @EnableWebFluxSecurity를 사용할까?
- 반응형 프로그래밍 지원
스프링 웹플럭스는 많은 수의 동시 요청을 효율적으로 처리하는 반응형 논블록킹 애플리케이션을 위해 설계되었습니다. @EnableWebFluxSecurity에서 활성화한 보안 구성은 이 반응형 프로그래밍 모델과 완전히 호환되므로 인증 및 승인과 같은 보안 작업도 차단되지 않고 반응형입니다. 이는 반응형 애플리케이션의 성능 및 확장성 이점을 유지하는 데 필수적입니다. - 스프링 클라우드 게이트웨이와의 통합
스프링 클라우드 게이트웨이는 스프링 웹플럭스 기반으로 구축된 반응형 API 게이트웨이이므로 원활한 통합을 위해 보안 기능도 반응형이어야 합니다. @EnableWebFluxSecurity를 사용하면 스프링 클라우드 게이트웨이의 반응형 프레임워크 내에서 작동하는 경로를 보호하고, 인증 메커니즘을 구성하고, 보안 필터를 적용할 수 있습니다 - 보안 필터 구성
웹플럭스 보안을 활성화하면 애플리케이션에 대한 보안 필터를 정의하고 사용자 지정할 수 있습니다. 이러한 필터는 다양한 경로에 대한 액세스를 제어하고, 인증 및 권한 부여를 처리하며, CSRF 보호, CORS 등의 보안 정책을 시행할 수 있습니다.
예를 들어, 게이트웨이에서 관리하는 모든 경로에 JWT 기반 인증을 적용하거나 사용자 역할에 따라 특정 경로에 대한 액세스를 제한할 수 있습니다.
Postman 테스트 - 회원가입, 로그인
'개발' 카테고리의 다른 글
[Springboot + Redis + CoolSms] 회원가입 인증 부분 문제 해결 (0) | 2024.09.06 |
---|---|
[Spring Cloud Gateway] 로그아웃 확인 (0) | 2024.09.05 |
[Spring Cloud Gateway] Springboot Eureka 설정 (0) | 2024.09.03 |
[SprinBoot] .yml key 문제 해결 (0) | 2023.10.27 |
[프로젝트 마무리] Swagger + postman 정리 (0) | 2023.10.07 |