| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- java
- middleware
- synchronized
- Google OAuth
- OAuth 2.0
- Dependency Injection
- builder
- 일급 객체
- spring security
- 일급 컬렉션
- factory
- Volatile
- nestjs
- lombok
- Spring
- Today
- Total
목록분류 전체보기 (191)
HJW's IT Blog
0. 배경저는 핵사고날 / 클린 / Port & Adapter 패턴에 대한 이해도가 부족하며 개인적인 회고를 위해 쓴 글임을 밝힙니다. 프로잭트를 진행하며 깊은 고민에 빠졌다. 지난 프로잭트들을 통해 뛰어난 유지보수성과 확장성을 위해선, OOP를 준수하는 코드의 작성이 필수에 가깝다는것을 배웠다. 서비스 코드를 작성하던 중, 한가지 의문점이 생겼다. DIP는 고수준 모듈이 저수준 모듈에 '직접' 의존해선 안된다는 원칙이다. 하지만 다음 코드를 보면 해당 서비스 클래스는 '직접' 저장소를 의존하고 있다.@Service@RequiredArgsConstructorpublic class MemberServiceImpl implements MemberService { private final MemberRepo..
0. 사전 지식대부분 알고 있겠지만, DBMS 의 트랜잭션 격리 수준은 4가지로 나뉜다.READ UNCOMITTED: 다른 트랜잭션이 commit 하지 않은 데이터도 보인다. Dirty Read 발생 가능READ COMITTED: 다른 트랜잭션이 commit 한 데이터만 보인다. 하지만 트랜잭션 실행 도중 데이터가 변경될 수 있다. Non Repeatable Read 발생 가능REPEATABLE READ: 트랜잭션에서 하나의 row 를 두번 조회하였을때 결과가 같음을 보장한다. 하지만 다건 조회의 경우 다를 수 있다. Phantom Read 가능SERIALIZABLE: 락을 거는 등, 고수준의 방법을 통해 한번에 하나의 트랜잭션만 해당 데터를 다룸을 보장한다.이러한 '격리'는 데이터의 무결성을 보장하기 ..
1. CSRF 란?Cross-Site Request Forgery 란, 사용자가 의도하지 않은 요청을 서버에 보내도록 유도하여 사용자의 권한을 악의적으로 사용하는 공격이다. 즉, 사용자의 권한을 사용하기 때문에 권한을 많이 가진 사용자 일수록 해당 공격에 노출되었을 때의 리스크가 높다. CSRF 공격이 가능하기 위해 다음 세가지 조건이 만족되어야 한다.상태 변경 작업 : 공격자가 어플리케이션 내에서 유도할 만한 동작이 존재해야 한다.쿠키 기반 세션 처리 : 작업을 수행하기 위해 공격자는 HTTP 요청에 의존하며, 어플리케이션은 사용자를 식별하기 위해 Session 쿠키에만 의존해야 한다.예측 가능한 요청 매개변수 : 공격자가 공격을 수행하기 위해 추측할 수 없는 매개변수가 있어선 안된다.대표적인 CSRF..
들어가며키워드 기반 조회 및 분류 작업을 할 때, 많은 개발자들이 LIKE %keyword% 연산자를 사용하곤 한다. 이 방식은 직관적이고 구현 난이도가 낮으나, 심각한 성능 저하를 일으 킬 수 있다. 이번 포스팅에선 이러한 단점을 극복하고 검색 성능을 획기적으로 향상시킬 수 있는 방법인 tsvector 와 GIN 인덱스 의 사용에 대해 알아 볼 것이다.tsvector 란?tsvector 는 PostgreSQL 에서 Full Text Search 를 위해 제공하는 특별한 데이터이다. 일반 텍스트 형태의 문서를 검색에 적합한 형태로 가공한 것으로, 고유한 lexeme들의 정렬된 목록을 제공한다. lexemes 란 형태 변화에 따라 변형되는 단어들의 뿌리 형태이다. 예를 들어 walk 는 여러 형태의 단어다..
1. 들어가며Spring Batch 를 활용해 뉴스 기사를 외부 API 에서 수집하고, 이 기사는 관심사 별로 분류하여 DB에 저장하는 과정에서의 시행착오를 담은 글이다. 2. 문제 파악기사 (Article)와 관심사 (Interest) 는 다대다 관계이다. 그렇기 때문에, 중간 테이블인 ArticleInterest 를 활용하여 저장하고자 하였다. Batch 의 전체 프로세스는 다음과 같았다.Reader :DB에서 Keyword 를 읽는다Keyword는 Interest 와 연결된 단어이다.기사를 조회할 때, Keyword 를 기반으로 조회한다Processor :각 Keyword 는 여러 Interest 와 연관되어 있을 수 있고, 하나의 Interest 는 여러 Keyword를 가질 수 있기 때문에, 이..
1. 개요AWS 와 같은 외부 서비스를 사용하는 어플리케이션은 테스트를 구성하기 까다롭다는 장벽이 있다. 외부 의존성, 비용, 네트워크 등의 이슈로 인해 테스트의 멱등성, 일관성 등이 보장되지 않으며, 테스트 코드가 올바르게 작성 되었지만 외부 이슈로 인해 실패할 수 도 있다. 이를 해결하기 위해 로컬 환경에서 AWS 를 모방하여 시뮬레이션 할 수 있도록 하는 LocalStack 을 활용하여 실제 AWS 서비스에 연결하지 않고도 AWS 의 다양한 서비스들을 시뮬레이션 해 볼 수 있다. 이번 포스팅에선, S3 기능을 테스트 해 보겠다. 2. Gradle 의존성다음과 같이 LocalStack 의존성을 추가해 주었다.testImplementation 'org.testcontainers:localstack:1..
1. VPC 란 무엇인가?AWS VPC 는 사용자의 AWS 공간 전용 가상 네트워크 이다. 이러한 가상 네트워크를 통해 사용자는 AWS 내 논리적으로 격리된 자신만의 네트워크 공간을 정의하고, VPC 안에서 안전하게 EC2 혹은 다른 AWS 리소스를 실행할 수 있다. 이러한 격리된 공간 내에선, 사용자가 리소스에 대해서 완전한 통제권을 가질 수 있게 만든다. VPC는 기존 온 프레미스 환경과 유사하게 격리된 가상 네트워크를 프로비저닝할 수 있다. 예를 들어 IP 주소 범위, Subnet, Routing Table 등을 정의하여 사용할 수 있다. 2. VPC 구성 옵션VPC 는 단일 구성 요소가 아닌 여러 구성요소들의 집합이다. 이러한 구성 요소들은 독립적인 역할을 수행 하면서도, 유기적으로 연결되어 ..
들어가며어플리케이션의 통합 테스트 코드를 작성하다 이해하기 힘든 상황을 마주쳤다.INSERT INTO users (id, created_at, updated_at, username, email, password, profile_id) VALUES ('00000000-0000-0000-0000-000000000001', NOW(), NOW(), 'user1', 'user1@example.com', 'encrypted-password', null); INSERT INTO users (id, created_at, updated_at, username, email, password, profile_id) VAL..
이전 포스팅에서 OAuth2.0 과 JWT 를 이용한 로그인 기능을 구현하였다. 이제 여기에 form login 방식을 추가하여 두가지 방식의 로그인을 가능하게 만들어 볼 것이다.UserDetails 와 UserDetailsServiceSpring Security 의 Form Login 을 이해하기 위해선, Spring Security 가 제공하는 UserDetails 객체와 UserDetailsService 를 이해하고 넘어가야 한다. 한번 UserDetails 를 살펴보자public interface UserDetails extends Serializable { Collection getAuthorities(); String getPassword(); String getUsername..
이번 사이드 프로젝트를 진행하며, OAuth 2.0 에 더불어 JWT 인증 시스템을 채택하여 진행하였다.OAuth 2.0 FlowClient 의 로그인 요청 : GET /api/oauth2/authorize/{provider} 로 요청을 보낸다서버는 돌아올 콜백 URI 를 포함한, 제공자에 맞는 URL 로 리다이렉션을 한다클라이언트가 제공자의 페이지에서 승인을 한다제공자는 콜백 URI 을 사용해 서버의 엔드포인트에 인증 코드를 포함해 보낸다서버는 해당 인증 코드를 가지고 다시 제공자에 Token요청을 한다Token 이 유효하다면, 제공자는 미리 명시된 (ex. email, providerId) 데이터를 서버로 보내준다.Spring Security 를 사용하게되면, 2 ~ 5번의 과정을 자동으로 진행해 준..