본문 바로가기

전체 글

[Spring] Bcrypt의 Salt 처리 방식 패스워드는 보통 평문이 아니라, 암호화 알고리즘을 통해 생성된 난수로 DB에 저장된다. 하지만 알고리즘을 통해 패스워드를 암호화 하더라도, 같은 문자열이라면 암호화 된 문자열 또한 같은 값이 나올 것이고, 이는 Rainbow Table을 이용한 공격에 취약하다는 것을 의미한다. 만약 아래와 같이 동일한 패스워드에 같은 "SHA-256" 알고리즘을 적용한다면... @Test void encodeTest() throws NoSuchAlgorithmException { String rawPassword = "password"; MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] firstHashedPassword = md.digest(rawPass.. 더보기
[Spring] Assertj 테스트 지원 메서드 Assertj 는기존 JUnit에서 제공하던 Assertions 테스트 클래스를 조금 더 가독성 있게 지원하는 자바 라이브러리이다. 테스트에 필요한 대부분의 메서드를 제공한다. 또한 메서드 체이닝을 지원하기 때문에, 가독성이 높다. 아래와 같이 의존성을 추가할 수 있지만, springboot-starter-test 를 implemetation 했다면 내장되어 있다. testImplementation 'org.assertj:assertj-core:3.22.0' 가장 기본적인 테스트로 동등성 검증이 있다. String test = "test"; assertThat(test).isEqualTo("test"); 아래와 같이 메서드 체이닝이 가능하다. String moreTest = "assertj asserti.. 더보기
[DB] 사용자에 따라 다른 Timezone 결과 조회하기(MariaDB) 글로벌 서비스를 지향하는 솔루션이라면, 언제나 피해갈 수 없는 것이 Timezone 문제일 것이다. 일반적으로 타임존을 다룰때는, 서버의 시간대를 사용하거나, UTC를 사용할 것이다. 하지만 사용자별로 Timezone을 Optional 하게 가져갈 수 있고, 설정한 타임존에 맞게 쿼리의 결과를 보여주어야 한다면 어떻게 하는것이 좋을까? 다양한 케이스와 환경의 차이가 있겠지만, 여기서는 내가 경험한 제한된 상황 그 환경 안에서 해결했던 방법을 적어보고자 한다. 직면한 환경과 제약사항은 아래과 같았다. RDBMS를 사용하고 있다. (MariaDB) MariaDB의 System 타임존은 UTC이다 (+00:00) 초당 데이터가 누적되고 있다. (unix timestamp 기준) 분, 시, 일 단위로 주기적으로.. 더보기
[Network] HTTP 버전별 특징 면접을 진행하면서 단골 질문이 될 수 있는 내용들에 대해 하나씩 공부하고, 정리중이다. HTTP/1.0 한 연결당 하나의 요청을 처리하도록 설계되었다. 이는 매 요청마다 3-way handshake를 계속해서 열어야 했기 때문에 RTT(Round Trip Time)가 증가한다는 단점이 있었다. 이를 해결하기 위해, 코드 압축, 이미지 Base64인코딩 등의 방법을 사용했다. HTTP/1.1 매번 TCP 연결을 하지 않고, 한 번 3-way handshake로 초기화를 한 후 keep-alive 옵션으로 여러개의 파일을 송수신 할 수 있게 되었다. keep-alive 옵션은 1.0에도 있기는 했지만 1.1부터 표준화 되었다. 그럼에도 불구하고 1.1에서는 문제가 여전히 존재한다. HOL Blocking(H.. 더보기
[Network] TCP & HTTP 비교 사람은 망각의 동물이다. 극복하는 방법은 반복밖에 없는 것 같다. 왜 이런 이야기를 하냐하면, 블로그에 포스팅까지 했던 내용으로 면접에서 털렸기 때문인데.. 다시금 기억을 되새기고 조금 더 자세하게 남겨보고자 이번 글을 적는다. 다들 알다시피 TCP와 HTTP는 모두 통신 프로토콜이고, ISO 7 Layer를 기준으로 TCP는 4계층인 전송(Transfort)계층 , HTTP는 7계층인 응용(Application) 계층이다. 이 말인 즉, HTTP는 결국 TCP기반 위에서 동작하는 프로토콜이라는 것이다. 그럼에도 불구하고 이 둘의 차이를 물어보는 것은 왜일까?. 가장 큰 차이는 "연결 지향적인 통신" 여부이다. HTTP는 비연결지향적인 단방향 통신인데, Client의 Request가 있을 경우, 서버는 .. 더보기
[Spring] Reactive Programming - Basic 비동기 프로그래밍을 처리하는 접근 방식중, 리액티브 프로그래밍에 대해 알아본다. 리액티브 프로그래밍은 "데이터나 이벤트의 변경이 발생하면 이에 반응해 처리하는 프로그래밍 기법"을 의미한다. "변경이 발생하면" 이라는 문구에서 옵저버 패턴을 쉽게 떠올릴 수 있는데, 실제로 이에 영감을 받아 설계되었으며, 손쉬운 비동기 처리를 위해 함수형 프로그래밍의 접근 방식을 사용한다. 리액티브 스트림(Reactive Stream) 리액티브 스트림은 리액티브 프로그래밍의 표준 API 사양을 의미한다. 리액티브 스트림은 TCK(Technology Compatibility Kit)을 지원하기 때문에 라이브러리가 사양에 맞게 구현되었는지 보장할 수 있다. 표준 사양을 채택한 대표적인 구현체는 Project Reactor, R.. 더보기
[Spring] 비동기 처리에 대한 이해(2) - CompletableFuture 일반적으로 Java나 Kotlin 비동기로 처리된 작업의 결과를 얻고자 하면 어떻게 하는가? Future 객체를 사용할 수 있다. ThreadExecutor에서 submit() 메서드를 사용하고 Callable 인터페이스를 통해 작업(Task)을 생성할 수 있다. 이 때 반환타입이 Future가 되는데, sum 메서드를 하나 생성 후 요청해보자. fun sum(a: Int, b: Int) = a + b fun main() { val pool = Executors.newSingleThreadExecutor() val future = pool.submit(Callable { sum(100, 200) }) println("계산 시작") val futureResult = future.get() //비동기 작업의.. 더보기
[Spring] 비동기 처리에 대한 이해(1) - 쓰레드 기본적으로 "스프링을 사용한다" 하면 대부분 Spring MVC를 이야기하는 것이고, 이는 동기(Synchronous)적 처리방식을 주로 사용한다는 것을 의미하기도 한다. 동기 처리방식은 순차적으로 동작하기 때문에, 코드를 파악하기 쉽고, 디버깅이 수월하다는 장점이 있다. 문제는 특정 작업을 실행하는 동안 해당 작업이 종료되기 전에 다른 작업을 진행할 수가 없다는 점이다. 스레드가 1개인 경우를 싱글 쓰레드(Single Thread), 둘 이상 존재하는 경우 멀티 쓰레드(Multi Thread) 라고 하고, Spring MVC 에서는 쓰레드의 갯수로 여러 작업을 비동기적으로 처리한다. (멀티 쓰레드 환경에서 스케줄링에 의해 쓰레드가 전환되면서 작업을 처리하는 것을 "컨텍스트 스위칭" 이라 한다)\ 일단 .. 더보기