공통 관심 사항(cross-cutting concerns)
📌 애플리케이션 전반에 걸쳐 여러 모듈이나 레이어에서 공통적으로 필요하지만, 특정 비즈니스 로직과 직접적으로 관련이 없는 기능을 의미합니다.
- 이러한 기능은 여러 곳에서 반복적으로 사용되며, 코드 중복을 초래하거나 모듈 간의 결합도를 높이는 원인이 될 수 있습니다.
같은 말로 횡단 관심사 라고 하며 여러 위치에서 공통적으로 사용되는 부가 기능이고 Filter가 나오게된 이유는 공통 관심사(Cross Cutting Concern)의 처리 때문이다. |
요구사항 : 로그인 한 유저만 특정 API를 사용할 수 있어야 한다. |
- 해결방법
- 언제나 핵심은 수정에 있다!
- 화면에서 로그인 하지 않으면 API를 사용하지 못하도록 막는다.
- 유저가 HTTP 요청을 마음대로 조작할 수 있다.
- Controller에서 로그인 여부를 체크하는 Logic을 작성한다.
- 실제로는 인증이 필요한 모든 컨트롤러에 공통으로 로그인 여부를 체크해야 한다.
- 로그인 로직이 변경될 때 마다 로그인 여부를 체크하는 Logic 또한 변경될 가능성이 높다.
@RestController
@RequestMapping("/post")
public class PostController {
@PostMapping
public PostResponseDto create(PostCreateRequestDto request) {
// 로그인 여부 확인 로직
// 생성 로직
}
@PutMapping("/{postId}")
public void update(
@PathVariable Long postId,
PostUpdateRequestDto request
) {
// 로그인 여부 확인 로직
// 수정 로직
}
@DeleteMapping("/{postId}")
public void delete(@PathVariable Long postId) {
// 로그인 여부 확인 로직
// 삭제 로직
}
}
- 위와같이 여러가지 로직에서 공통으로 관심이 있는 부분을 공통 관심사 라고 한다.
로그인 여부 확인 로직 -> 공통 관심사 (인증 : 로그인) |
- 공통 관심사는 로그인뿐만 아니라 더 큰범위를 의미한다.
- Spring AOP를 활용할 수 있다.
- Web과 관련된 공통 관심사는 Servlet Filter나 Spring Intercepter를 사용한다.
- HttpServletRequest 객체를 제공하기 때문에 HTTP 정보나 URL 정보에 접근하기 쉽다.
- ex ) 특정 URL의 요청은 인증을 할것이다. → URL 정보 필요
Spring AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)
📌 로깅, 보안, 트랜잭션 관리 등과 같은 횡단 관심사를 개별적인 Aspect(관점)로 모듈화할 수 있도록 합니다.
- 이를 통해 핵심 비즈니스 로직과 부가적인 로직을 분리하여 코드의 가독성과 유지보수성을 높일 수 있습니다.
- 반복되는 공통 작업(예: 로깅, 보안, 트랜잭션 관리)을 한 곳에 모아서 관리할 수 있게 도와준다. 예를 들어 모든 메서드 실행 전에 로그를 냄기는 경우, 각 메서드에 System.out.println()을 넣는 대신, AOP로 한번만 설정하면 알아서 모든 메서드에 적용된다.
Spring AOP의 주요 개념
- Aspect(관점)
- 횡단 관심사를 정의한 모듈입니다. 예: 로그 기록, 트랜잭션 관리.
- Join Point(조인 포인트)
- 애플리케이션 실행 과정에서 Aspect를 적용할 수 있는 지점입니다. 예: 메서드 호출, 예외 발생.
- Advice(어드바이스)
- Join Point에서 실행되는 작업(Aspect의 구체적인 동작)입니다. Advice는 다음과 같이 구분됩니다:
- Before: 메서드 실행 전에 실행.
- After: 메서드 실행 후에 실행.
- Around: 메서드 실행 전후에 실행.
- After Returning: 메서드가 정상적으로 반환된 후 실행.
- After Throwing: 메서드 실행 중 예외가 발생한 후 실행.
- Join Point에서 실행되는 작업(Aspect의 구체적인 동작)입니다. Advice는 다음과 같이 구분됩니다:
- Pointcut(포인트컷)
- Advice가 적용될 Join Point를 정의하는 표현식입니다.
- Weaving(위빙)
- Aspect를 애플리케이션의 대상 객체에 적용하는 과정입니다. Spring AOP에서는 런타임 위빙이 일반적으로 사용됩니다.
Spring AOP 특징
- Spring AOP는 프록시 기반으로 동작합니다.
- 런타임 기반 AOP를 지원하며, Java 동적 프록시나 CGLIB를 사용합니다.
- 메서드 호출 수준의 AOP를 제공합니다. (클래스 내부의 필드 변경 등에는 적용되지 않음)
Spring AOP 사용 방법
1. 의존성 추가 Spring AOP를 사용하려면 Maven 또는 Gradle에 관련 의존성을 추가합니다:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>버전</version>
</dependency>
2. Aspect 정의 아래는 간단한 로그 Aspect 예제입니다:
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("메서드 실행 전: " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("메서드 실행 후: " + joinPoint.getSignature().getName());
}
}
3. Pointcut 표현식
- execution(* 패키지명.클래스명.메서드명(..)): 특정 메서드에 적용.
- within(패키지명..*): 특정 패키지 내 모든 클래스에 적용.
- @annotation(애너테이션): 특정 애너테이션이 적용된 메서드에만 적용.
4. AOP 활성화 AOP 기능을 활성화하려면 @EnableAspectJAutoProxy 애너테이션을 사용합니다:
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
Proxy
📌 대리자라는 의미로, 컴퓨터 네트워킹에서 주로 클라이언트와 서버 간의 중간에 위치하여 데이터를 중계하는 서버 또는 소프트웨어를 지칭합니다.
1. 프록시의 주요 개념
- 중간자 역할: 프록시는 클라이언트가 서버에 직접 요청을 보내지 않고, 프록시를 통해 요청과 응답이 오가게 만듭니다.
- 주소 은폐: 클라이언트의 실제 IP 주소를 감추고, 프록시 서버의 IP를 사용하여 요청을 처리합니다.
- 트래픽 제어: 요청을 필터링하거나 캐싱하는 등 트래픽을 관리합니다.
2. 프록시의 유형
1) 포워드 프록시 (Forward Proxy)
- 동작: 클라이언트가 프록시 서버를 통해 인터넷에 요청을 보냅니다.
- 사용 사례:
- IP 숨김: 사용자의 IP 주소를 감추고 다른 주소로 대체.
- 콘텐츠 우회: 지역 제한된 콘텐츠(예: 특정 국가에서 차단된 웹사이트) 접근.
- 캐싱: 자주 요청되는 데이터를 저장하여 빠른 응답 제공.
2) 리버스 프록시 (Reverse Proxy)
- 동작: 서버 앞단에 위치하며, 클라이언트 요청을 받아 적절한 서버에 전달.
- 사용 사례:
- 로드 밸런싱: 여러 서버로 트래픽을 분산하여 서버 과부하 방지.
- 보안: 서버의 실제 위치(IP)를 숨기고 공격으로부터 보호.
- SSL 종단: HTTPS 암호화를 처리하여 서버 부담 감소.
3) 오픈 프록시 (Open Proxy)
- 동작: 전 세계 누구나 사용할 수 있는 공개 프록시 서버.
- 특징: 익명성을 제공하지만 보안 문제가 있을 수 있음.
- 주의사항: 악의적인 활동에 이용될 가능성이 높음.
4) 투명 프록시 (Transparent Proxy)
- 동작: 사용자에게 보이지 않는 방식으로 트래픽을 중계.
- 사용 사례:
- 네트워크 관리자에 의해 웹 필터링이나 모니터링.
- 기업 및 공공기관에서 사용.
5) SOCKS 프록시
- 특징: TCP와 UDP 트래픽을 모두 처리 가능.
- 사용 사례:
- P2P 파일 공유(예: 토렌트).
- 게임에서 지연 감소 및 지역 제한 우회.
6) VPN과의 차이
- VPN은 네트워크 트래픽 전체를 암호화하는 반면, 프록시는 특정 트래픽만 처리.
- 프록시는 보안보다는 익명성과 요청 중계를 중심으로 함.
3. 프록시 사용 사례
- 보안 및 익명성 제공
- 사용자의 실제 IP를 숨기고, 온라인 활동을 익명으로 수행.
- 콘텐츠 필터링 및 접근 제한
- 기업이나 학교에서 불법적이거나 부적절한 콘텐츠 접근 차단.
- 지역 제한 콘텐츠 우회
- 예: 특정 국가에서 차단된 Netflix 콘텐츠를 시청.
- 트래픽 최적화
- 캐싱을 통해 대역폭을 줄이고, 요청 속도를 높임.
- 분산 처리
- 리버스 프록시를 사용하여 대규모 트래픽을 여러 서버로 나누어 처리.
- 데이터 로깅 및 모니터링
- 네트워크 트래픽 분석 및 기록.
- 테스트 및 디버깅
- 웹 개발에서 네트워크 요청과 응답을 확인하거나 조작.
4. 프록시 사용 시 고려사항
- 성능:
- 추가적인 네트워크 홉으로 인해 지연이 발생할 수 있음.
- 보안:
- 신뢰할 수 없는 프록시 서버 사용 시 개인 정보가 유출될 위험.
- 법적 문제:
- 지역 제한 콘텐츠 우회 등은 해당 국가의 법률을 위반할 수 있음.
- 설정 복잡성:
- 특정 애플리케이션이나 네트워크 환경에서는 복잡한 설정이 필요할 수 있음.
아래는 **프록시(Proxy)**와 유사 기술(VPN, NAT, 방화벽 등)을 비교한 표입니다. 각 기술의 특징, 주 용도, 장단점을 기준으로 작성했습니다.
기술 | 주요 특징 | 주 용도 | 장점 | 단점 |
프록시 (Proxy) | 클라이언트와 서버 간의 중계 역할. 특정 요청과 응답만 처리. | 익명성 제공, 콘텐츠 필터링, 캐싱, 로드 밸런싱 | 익명성 제공, 특정 요청만 중계 가능, 네트워크 효율성 증대 | 암호화 부족, 전체 트래픽 보호 불가, 설정 복잡도 |
VPN | 클라이언트와 서버 간의 모든 네트워크 트래픽을 암호화된 터널을 통해 전송. | 전체 트래픽 보호, 지역 제한 우회, 공공 네트워크 보안 | 강력한 암호화, 전체 네트워크 보호, 위치 은폐 | 느린 속도(암호화로 인한 지연), 서버 설정 복잡도 |
NAT | 내부 네트워크의 사설 IP를 공인 IP로 변환하여 인터넷 접속을 가능하게 함. | 내부 네트워크 주소 은폐, 인터넷 접속 공유 | 네트워크 자원 효율적 사용, 기본적인 보안 제공 | 특정 연결 설정 어려움(포트 포워딩 필요), 정교한 보안 기능 부족 |
방화벽 (Firewall) | 네트워크 트래픽을 모니터링하고, 사전 정의된 규칙에 따라 허용 또는 차단. | 네트워크 보안, 공격 방지, 접근 제어 | 높은 보안성, 트래픽 모니터링 가능 | 설정 복잡도, 성능 저하 가능 |
CDN | 클라이언트 요청을 가장 가까운 서버로 라우팅하여 콘텐츠를 빠르게 제공. | 콘텐츠 전송 속도 향상, 대규모 트래픽 처리 | 빠른 속도, 지연 시간 감소, 서버 부하 감소 | 실시간 처리 제한, 동적 콘텐츠 캐싱 어려움 |
로드 밸런서 | 여러 서버에 네트워크 트래픽을 분산하여 서버의 부하를 줄임. | 서버 성능 최적화, 고가용성 제공 | 서버 부하 감소, 고가용성 제공 | 초기 설정 복잡, 추가 하드웨어/소프트웨어 필요 |
TOR (Onion Routing) | 익명 네트워크로 트래픽을 여러 노드에 암호화해 전송하여 사용자의 위치와 활동을 감춤. | 높은 익명성 제공, 검열 우회 | 익명성 보장, 검열 우회 가능 | 느린 속도, 네트워크 신뢰성 부족, 악성 노드 가능성 |
SOCKS 프록시 | TCP 및 UDP 트래픽 모두 지원하며, 특정 애플리케이션 트래픽만 중계. | P2P 파일 공유, 게임 지연 감소, 특정 트래픽 익명화 | 유연성 높음, 애플리케이션별 설정 가능 | 암호화 부족, 전체 네트워크 보호 불가 |
Servlet Filter
📌 클라이언트의 요청(request) 및 응답(response)을 처리하거나 조작하기 위해 사용되는 컴포넌트( 소프트웨어 개발에서 재사용 가능하고 독립적인 기능 단위 )
- Servlet Filter는 보안, 로깅, 인코딩, 인증/인가 등 다양한 작업을 처리하기 위해 사용된다.
Servlet Filter 특징
- 공통 관심사 로직 처리
- 공통된 로직을 중앙 집중적으로 구현하여 재사용성이 높고 유지보수가 쉽다.
- 모든 요청이 하나의 입구를 통해 처리되어 일관성을 유지한다.
- HTTP 요청 및 응답 필터링
- Filter Chain
- 여러 개의 필터가 순차적으로 적용될 수 있다.
- filterChain.doFilter(request, response); 다음 필터로 제어를 전달한다.
- doFilter()
- 실제 필터링 작업을 수행하는 주요 메소드로 필터가 처리할 작업을 정의한다.
- 다음 필터로 제어를 넘길지 여부를 결정한다.
Servlet Filter 적용
- Filter를 적용하면 Servlet이 호출되기 이전에 Filter를 항상 거치게된다.
- 공통 관심사를 필터에만 적용하면 모든 요청 or 응답에 적용된다 .
- Filter는 특정 URL Pattern에 적용할 수 있다.
- Spring을 사용하는 경우 Servlet은 **Dispatcher Servlet**이다.
Servlet Filter와 Servlet의 차이점
항목Servlet FilterServlet
주요 목적 | 요청/응답 전후의 처리 | 클라이언트 요청을 처리하고 응답 생성 |
체인 가능성 | 여러 필터를 체인 방식으로 연결 가능 | 독립적으로 동작 |
적용 대상 | 서블릿, JSP, 정적 리소스 등 모든 요청 | 특정 URL에 대한 요청만 처리 |
작업 위치 | 요청/응답 전후 | 요청 처리 내부 |
Servlet Filter와 Listener 비교
항목Servlet FilterServlet Listener
주요 역할 | 요청/응답 흐름을 가로채고 처리 | 특정 이벤트(애플리케이션, 세션 등) 처리 |
적용 대상 | 클라이언트 요청/응답 흐름 | 컨텍스트, 세션, 요청 수명 주기 |
예제 | 로깅, 인증, 캐싱 | 세션 생성/소멸, 애플리케이션 초기화 |
Filter Interface
📌 Java Servlet에서 HTTP 요청과 응답을 중간에서 처리, 이를 기반으로 다양한 처리 작업을 수행하는 데 사용되는 Interface이다.
- 클라이언트 → 요청 → 필터 → 서블릿/JSP → 응답 → 필터 → 클라이언트
Filter Interface의 사용 사례
- 인증(Authentication) 및 권한 부여(Authorization):
- 특정 페이지에 접근하려는 클라이언트를 필터에서 확인하고, 인증되지 않은 사용자라면 로그인 페이지로 리디렉션.
- 로깅(Logging):
- 요청의 정보를 기록(예: 요청 URL, 클라이언트 IP, 요청 시간 등).
- 데이터 유효성 검사:
- 클라이언트의 요청 데이터를 확인하고, 잘못된 값이 있으면 필터 단계에서 차단.
- 응답 데이터 변환:
- 서버의 응답 데이터를 필터에서 압축하거나 특정 포맷(예: JSON)으로 변환.
- 보안 처리:
- HTTP 요청의 헤더를 검사해 보안 위협(예: XSS, CSRF)을 탐지 및 차단.
jakarta.servlet.Filter
- Filter Interface를 Implements하여 구현하고 Bean으로 등록하여 사용한다.
- Servlet Container가 Filter를 Singleton 객체로 생성 및 관리한다.
주요 메서드
- init()
- Filter를 초기화하는 메서드이다.
- Servlet Container가 생성될 때 호출된다.
- default ****method이기 때문에 implements 후 구현하지 않아도 된다.
- doFilter()
- Client에서 요청이 올 때 마다 doFilter() 메서드가 호출된다.
- doFilter() 내부에 필터 로직(공통 관심사 로직)을 구현하면 된다.
- WAS에서 doFilter() 를 호출해주고 하나의 필터의 doFilter()가 통과된다면
- Filter Chain에 따라서 순서대로 doFilter() 를 호출한다.
- 더이상 doFilter() 를 호출할 Filter가 없으면 Servlet이 호출된다.
- Client에서 요청이 올 때 마다 doFilter() 메서드가 호출된다.
- destroy()
- 필터를 종료하는 메서드이다.
- Servlet Container가 종료될 때 호출된다.
- default method이기 때문에 implements 후 구현하지 않아도 된다.
Servlet Filter 구현
- Filter 구현체
- 요청 URL을 Log로 출력하는 Filter
@Slf4j
public class CustomFilter implements Filter {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain
) throws IOException, ServletException {
// Filter에서 수행할 Logic
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
log.info("request URI={}", requestURI);
// chain 이 없으면 Servlet을 바로 호출
chain.doFilter(request, response);
}
}
doFilter() 는 더 이상 호출할 Filter가 없다면 Servlet을 호출한다.
ServletRequest 는 기능이 별로 없어서 대부분 기능이 많은 HttpServletRequest 를 다운 캐스팅 하여 사용한다. |
Filter 등록
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean customFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
// Filter 등록
filterRegistrationBean.setFilter(new CustomFilter());
// Filter 순서 설정
filterRegistrationBean.setOrder(1);
// 전체 URL에 Filter 적용
filterRegistrationBean.addUrlPatterns("/*");
return filterRegistrationBean;
}
}
- setFilter()
- 등록할 필터를 파라미터로 전달하면 된다.
- setOrder()
- Filter는 Chain 형태로 동작한다.
- 즉, 실행될 Filter들의 순서가 필요하다.
- 파라미터로 전달될 숫자에 따라 우선순위가 정해진다.
- 숫자가 낮을수록 우선순위가 높다.
- addUrlPatterns()
- 필터를 적용할 URL 패턴을 지정한다.
- 여러개 URL 패턴을 한번에 지정할 수 있다.
- 규칙은 Servlet URL Pattern과 같다.
- filterRegistrationBean.addUrlPatterns("/*")
- 모든 Request는 Custom Filter를 항상 지나간다.
Spring이 제공하는 URL Pattern은 Servlet과 다르게 더욱 세세하게 설정할 수 있다. |
Servlet Filter 정리
- Filter를 사용하려면 Filter Interface를 Implements 하여 구현한다.
- 구현한 Filter를 Bean으로 등록 한다.
- HTTP 요청이 오면 doFilter() 메서드가 호출된다.
- ServletRequest는 기능이 별로 없어서 HttpServletRequest로 다운 캐스팅 해야한다.
- chain.doFilter(request, response)
- (순서를 설정해둔)다음 필터가 있으면 Filter를 호출한다.
- 다음 실행할 필터가 없으면 Servlet을 호출한다.
- 해당 메서드를 호출하지 않으면 다음 단계로 진행되지 않는다.
- 다음 필터나 Servlet을 호출하지 않는다.
- Filter를 등록하는 방법은 여러가지가 있다.
- SpringBoot의 경우 FilterRegistrationBean 을 사용한다.
'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글
[Net] Session & Cookie의 관계 (0) | 2024.12.31 |
---|---|
[Net] Token & JWT (0) | 2024.12.29 |
[Net] Cookie (1) | 2024.12.28 |
[Net] MVC 패턴 (0) | 2024.12.13 |
[Net] API 설계 (0) | 2024.12.12 |