spring
-
HandlerMethodArgumentResolver 동작 원리spring/core 2021. 3. 8. 23:06
배경 프로젝트에서 가장 기본 도메인인 회원의 CRUD를 구현하고 있었다. JPA를 이용해 큰 어려움 없이 CR기능은 구현했고 스무스하게 UD관련 기능을 구현했다. 별 고민없이 클라이언트에서 회원id와 함께 변경에 필요한 데이터를 api서버로 전달했다. api서버에서는 회원id와 나머지 변경을 원하는 데이터를 DTO로 받아 작업을 처리했다. 포스트맨을 이용해 간단히 테스트를 진행했는데 내 로직에 큰 결함이 있는 걸 알았다. id를 클라이언트에서 넘긴 후 그 id로 조회한 회원의 데이터를 수정할 수 있다면 어떤 회원이 악의적으로 다른 회원의 데이터를 수정할 수 있었다. 즉, 서버에서 인증한 회원이라면 다른 회원의 정보를 임의의 id를 통해 접근할 수 있는 것이었다. 이 문제를 해결하기 위해 id에 의존한 회..
-
AOP 동작 원리spring/core 2021. 3. 6. 01:05
배경 토비의 스프링 실습 공부 AOP의 등장 배경을 코드로 익히면서 실제 스프링이 재사용 가능한 범용적인 AOP를 어떻게 적용하는지 코드를 통해 알아보자. 개인적으로 내용이 길고 어려워서 몇 번 씩 반복 중이다. 요구사항의 변화 위와 같이 메세지를 전달받으면 간단하게 Hello를 추가한 메세지를 반환하는 오브젝트가 있다고 해보자. Hello서비스를 이용하는 클라이언트는 메세지를 넣으면 자동으로 Hello를 추가해주는 기능에 만족하고 있었다. 이때 클라이언트는 위 메소드가 실행될 때마다 콘솔에 시작을 알리는 텍스트를 찍고 메소드가 끝나기직전에 끝을 알리는 텍스트를 찍어주는 기능을 추가해 달라고 요청했다. 단순하게 구현이 가능하지만, 만약 클래스의 메소드가 100개였다면 어땠을까? 간단하게 100개의 메소드..
-
SecurityContextHolder의 역할 및 원리spring/security 2021. 3. 3. 13:55
배경 WAS를 구성할 때 유저의 인증 인가를 관리하는 프레임워크로 spring security를 선택했다면securityContextHolder를 사용해본 경험이 있을 거다. 지금 내 프로젝트에서도 비지니스로직에서 게시물을저장할 때 SecurityContextHolder를 사용해 게시물의 작성자를 등록하고 있다.(이렇게 비지니스로직에 기술종속적 코드가 나오는 게 안 좋은 것 같긴 하다 => 아규먼트리졸버로 미리 처리) SecurityContextHolder의 역할은 간단하다. 객체의 세션을 CRUD하는 API를 제공하고 사용하면 그만이다. 하지만 본인은 코드 상에서 세션을 따로 저장한 적도 없을 뿐더러 세션을 get할 때 HttpRequest를 파라미터로 제공하는 웹 기술에 종속적인 방식을 사용하지 않는..
-
-
양방향 연관관계와 CASECADE 옵션spring/JPA 2021. 2. 25. 00:56
프로젝트를 진행하던 중 게시글 입력 규칙을 바꾸기로 했다. 기존 게시글은 본인의 이력을 입력하는 필드가 있었는데 이 입력 필드의 개수는 2개로 고정되어 있었다. 요구사항이 변경돼 사용자는 입력 필드를 동적으로 추가하거나 삭제할 수 있게 했다. 변경된 요구사항을 반영하기 위해 JPA와 RDB의 설계를 수정했다. 우선, RDB에서는 간단하게 동적 필드를 테이블로 분리했다. 분리한 테이블은 고유ID를 갖고 게시글의 ID를 FK로 갖는다. 다음으로 JPA 수정에 들어 갔다. 게시글과 이력의 관계는 1:N관계 즉, 한 게시글은 N개의 이력을 갖는다. JPA에서 1:N관계를 설계할 때 고려해야할 2가지 사항이 있다. 첫째는 연관관계를 단방향으로 가질지 양방향으로 가질지를 결정해야 한다. 대부분의 객체는 단방향으로 ..
-
spring session 아키텍처spring/session 2021. 2. 22. 12:35
현재 프로젝트는 session을 was의 메모리에서 관리하고 있다. 이 방법은 내가 지정한 방법이 아니라, tomcat이 기본으로 실행하고 있는 방법이다. 요청에 대한 getSession()이 호출되는 시점에 쿠키 설정부터 쿠키와 세션을 저장하기까지 was가 다 해준 것이다. 구현은 편리하지만, 서버 확장 시 큰 문제가 생긴다. 논리적으로 동일한 서버지만 물리적으로 다른 서버라면 세션의 동기화가 필요하다. 또한, was의 메모리를 직접 할당해 세션을 관리하므로 공간적 제약도 고려해야 한다. 결국 세션 저장소를 분리하기로 했고, Filter로 spring session을, 저장소로 redis를 사용하기로 했다. boot를 이용한 프로젝트에서 의존성을 추가하고, application.yml에 필요한 정보를 ..
-
Spring Security 아키텍처spring/security 2021. 2. 21. 01:29
늘 그렇듯 아키텍처를 이해하는 게 모든 커스터마이징의 기본이다. 현재 프로젝트의 세션 관리는 전부 was내에서 처리한다. 나중에 서비스가 커져서 was를 분산하거나, 한 was에 모든 세션을 저장하기 부담스러운 상황이 온다면? redis를 이용해 세션을 was에서 분리하는 목표를 세웠다. 그전에, servlet으로 가기 이전인 filter기반으로 동작하는 스프링 시큐리티 아키텍처를 이해해보자. 스프링 WAS의 큰 그림 클라이언트의 요청이 오면 요청은 FilterChain으로 이루어진 Filter를 하나씩 거치게 된다. 모든 Filter를 거친 후 최종적으로 servlet에 요청을 위임한다. 이때 spring security는 servlet에게 요청을 위임하기 전에 인증, 인가만 따로 처리하는 하나의 Fi..
-
Spring Security를 적용한 Web Layer 테스트하기spring/test 2021. 2. 11. 12:50
클라이언트로부터 http요청을 받아 서비스계층으로 요청을 위임하는 Controller는 단위테스트가 불가능하다고 생각했다.애초에 복잡한 비지니스로직보다는 http요청을 잘 전달받고 서비스계층에게 역할을 위임한 후 올바른 데이터가 올 것이란 믿음과 함께 request를 잘 리턴하기만 하면 됐기 때문이다. 테스트를 하더라도 @SpringBootTest와 postman을 이용한 테스트를 했었고, 이는 결국 실제 애플리케이션을 띄우는 작업과 다를 바 없는 무의미한 테스트로 생각했다. 결국 테스트코드를 이용한 자동화 테스트보다는 서버를 띄운 수동테스트를 주로 했었다. 그러던 중, @WebMvcTest에 대한 예제를 확인했고, @SpringBootTest보다 훨씬 가벼운 준?통합 테스트를 확인했다.(자동화가 가능한..