Spring
17 posts
Spring
September 11, 2024
Reactor에서 `publishOn`과 `subscribeOn`의 역할

Reactor에서 과 의 역할 Spring WebFlux를 공부하기 위해서는 먼저 Reactor에 대해 이해하는 것이 중요하다. 특히, Reactor에서 제공하는 ****과 ****은 리액티브 스트림에서 중요한 개념이다. 이 두 가지 연산자는 비동기적으로 데이터 스트림을 처리하는 과정에서 스레드를 제어하는 역할을 한다. 이번 포스팅에서는 과 이 무엇인지, 그리고 어떻게 다르게 동작하는지에 대해 알아보자. 이란? ****은 말 그대로 구독 시점과 데이터 생성을 어느 스레드에서 실행할지를 결정하는 연산자다. 즉, 이 연산자가 적용되면 구독이 시작되는 순간부터 데이터가 생성되는 시점까지 특정 스레드에서 작업이 실행된다. 적용 시점: 체인의 어디에 위치하든 상관없이, 구독 시점부터 영향을 미친다. 영향 범위: 구독과 데이터 생성 전체에 영향을 미친다. 예시 위 예시에서는 이 설정되었기 때문에, 로 생성된 데이터는 스레드에서 처리된다. 즉, 데이터가 만들어지는 시점과 구독 시점이 elas…

Backend
Spring
September 07, 2024
컴파일러, JIT, AOT, Graal, 그리고 Spring Native 이해하기

컴파일러, JIT, AOT, Graal, 그리고 Spring Native 이해하기 💡 이 포스트에서는 컴파일러, Just-In-Time(JIT), Ahead-Of-Time(AOT) 컴파일, GraalVM, 그리고 이들이 Spring Native와 어떻게 연관되는지에 대해 살펴본다. 이러한 개념들은 자바 및 다른 언어들이 다양한 런타임 환경에서 어떻게 작동하는지 이해하는 데 중요한 역할을 하며, Spring 애플리케이션이 이 기술들을 통해 성능을 최적화할 수 있는 방법을 제공한다. 1. 컴파일러란 무엇인가? 컴파일러는 프로그래밍 언어로 작성된 소스 코드를 기계어로 변환하는 도구이다. 두 가지 주요 컴파일 방식이 있다: 정적 컴파일 (예: javac): 프로그램이 실행되기 전에 소스 코드를 기계어 또는 중간 형태로 변환한다. 자바에서는 파일을 파일(바이트코드)로 변환하는 과정이다. 동적 컴파일 (예: JIT): 프로그램이 실행되는 동안 코드의 일부를 기계어로 변환한다. 2. Jus…

Spring
SpringSecurity
June 26, 2024
AuthenticationProvider and Housekeeping

AuthenticationProvider and Housekeeping AuthenticationProvider 고객의 요구사항은 다양할 수 있다. 예를 들어, 어떤 고객은 애플리케이션에서 인증을 수행하는데 유저이름과 비밀번호를 사용하고 싶을 수 있고, 어떤 고객은 OAuth2를 사용하고 싶을 수도 있다. 또 어떤 고객은 몇몇 서비스에 OTP를 적용하는 것을 고려할지도 모른다. 이렇게 수 많은 경우의 요구사항을 프레임워크에서 모두 준비해 줄 수 없기 때문에, 우리는 우리만의 를 커스텀하여 사용해야 한다. AuthenticationProvider 내에는 두 가지 추상 메서드가 있다. 첫 번째는 메서드이다. 반환하는 객체는 인증이 성공적이었는지에 대한 정보를 가지고 있어야 가 다른 를 시도해 볼 수 있다. 두 번째는 메서드이다. 해당 메서드는 우리가 커스텀하는 가 어떤 종류의 인증을 지원하고 싶은지를 서술한다. 어떤 종류의 인증에 관해 이 가 부름을 받아야 하는지 프레임워크에 알려주…

Spring
SpringSecurity
June 26, 2024
Spring Security PasswordEncoder

Spring Security PasswordEncoder Encoding, Encryption and Hashing 고객의 데이터를 저장할 때, 비밀번호와 같은 민감한 값은 Plaintext 형태로 직접 저장해서는 안된다. 데이터 보안의 핵심은 이러한 민감한 정보를 안전하게 보호하는 것이다. 이를 위해 흔히 사용하는 세 가지 방법은 Encoding, Encryption, 그리고 Hashing이다. 각 방법의 특징과 차이점을 이해하는 것은 매우 중요하다. Encoding 목적: 데이터를 다른 형식으로 변환하여 전송하거나 저장하는 과정. 특징: 데이터의 변환은 가독성을 높이기 위한 것이며, 정보 자체의 보안을 고려하지 않는다. 가역성: 가역적이다. 즉, 원래 데이터로 복원할 수 있다. 예: Base64, URL Encoding 등. Encryption 목적: 데이터를 암호화하여 권한이 없는 사람이 읽을 수 없도록 보호. 특징: 암호화 키를 사용하여 데이터를 변환하며, 해당 키를 사용…

Spring
SpringSecurity
June 25, 2024
Spring Security 유저 관리 인터페이스

Spring Security 유저 관리 인터페이스 기본 설정에서의 스프링 시큐리티 시퀀스 기본 설정에서 의 구현체인 를 사용하고, 의 구현체인 를 사용했다. 는 의 확장인 의 구현체인 를 사용했다. 위 내용은 아주 중요하니 숙지하고 들어가야 한다. UserDetails 이전 섹션에서 설명한 /는 유저 정보를 표현하기 위해 인터페이스를 사용한다. 한 번 인터페이스를 살펴보자 : 이 메서드는 엔드 유저의 권한 또는 역할 목록을 보유하고 있고 그래서 이를 이용하여 인가 또는 역할 기반 엑세스 메커니즘을 구현할 수 있다. : 엔드 유저의 비밀번호를 반환한다. : 엔드 유저의 유저 이름을 반환한다. 기본 세부 정보 이후에 유저 계정이 만료되었는지, 잠겨 있는지, 자격 증명이 만료되었는지 등을 확인하는데 도움이 되는 몇가지 다른 메서드들도 제공한다. User 스프링 시큐리티 팀은 를 구현한 를 샘플로 제공한다. 우리는 이 구현체가 마음에 들지 않으면 커스텀한 새로운 구현체를 만들어…

Spring
SpringSecurity
June 24, 2024
Spring Security 기본 설정, 커스텀

Spring Security 기본 설정, 커스텀 기본 필터체인 을 확인하면 다음과 같이 기본 필터체인이 등록되었음을 확인할 수 있다. : 이 구문은 해당 필터체인의 인가 규칙을 정의한다. : 모든 요청에 대해 인증이 필요하다고 설정한다. ⚠️ 최신 스프링 시큐리티에서는 TypeCasting 없이 사용할 수 있도록 개선됐다. -> : 폼 기반 로그인을 설정한다. 프론트엔드와 백엔드가 나뉘어 http로 유저네임과 비밀번호를 전송하는 경우에는 사용하지 않는다. : http 기본 인증을 설정한다. 이 설정은 http 헤더를 통해 인증을 수행할 수 있도록 한다. -> 이는 JWT의 그것과 다르다. 자세한 내용은 아래 참조. HTTP Basic 인증 과정 클라이언트 요청: 클라이언트는 보호된 리소스에 접근하기 위해 서버에 HTTP 요청을 보냅니다. 이때 클라이언트는 아직 인증되지 않은 상태입니다. 서버의 인증 요구: 서버는 클라이언트가 인증되지 않았음을 인지하고, 401 Unauth…

Spring
SpringSecurity
June 24, 2024
Spring Security 디버깅

Spring Security 디버깅 Spring Security Filters 스프링 프레임워크는 Tomcat 서블릿 컨테이너 위에서 돌아가므로 Tomcat의 서블릿 필터 기능에 의존한다. 스프링 시큐리티를 사용하게 되면 이 Tomcat의 FilterChain에 스프링 시큐리티 전용 필터를 하나 끼워넣어 모든 요청을 가로채는데, 이것이 바로 이다. 는 기타 로직이 하나도 없이 단지 스프링 프레임워크 내부의 빈으로 요청을 넘겨주는 프록시 역할만을 할 뿐이다. 는 엔드 유저의 요청에 따라 스프링 시큐리티가 관리하는 을 호출하여 요청을 거기로 프록시한다. 는 인증 및 인가와 관련된 여러 사항을 검증하고 적절한 응답을 반환하는 것을 목표로 한다. 는 위 그림과 같이 여러개로 구성될 수 있으며, 엔드 유저의 요청 URL에 따라 가 적절한 에게 프록시 해준다. Default Spring Security Filter Chain 를 열어보면 다음과 같은 메서드를 확인할 수 있다. 이 메…

Spring
SpringSecurity
June 23, 2024
Spring Security 내부 흐름

Spring Security 내부 흐름 플로우 다이어그램 사용자가 웹 어플리케이션에 자격증명 정보를 입력한다. 이 정보는 으로 넘겨진다. 는 사용자가 입력한 자격증명을 가로채고, 접근 권한이 있는지 확인한다. FIlter Chain에는 : 사용자 이름과 비밀번호를 통한 인증을 처리 : HTTP Basic 인증을 처리 : CSRF 공격을 방지 : 로그아웃 요청을 처리 와 같은 필터들이 있을 수 있다. 는 엔드유저가 보낸 자격증명 정보에서 유저네임과 비밀번호를 추출하여 객체로 변환한다. 에 이미 정보가 존재하는 경우는 이후 해당 객체를 사용하고, 과정을 스킵한다. 객체는 스프링 시큐리티 프레임워크 안에서 엔드유저의 정보를 저장하기 위한 핵심 표준이다. 2단계에서는 유저네임와 자격증명만을 보유한다. 바로 다음과 같은 것들이다. : 사용자 이름 또는 사용자 식별자 : 사용자가 입력한 비밀번호 이후의 인증 과정에서 이 객체에는 더 많은 책임과 역할이 부여될 수 있다. 는 생성된…

Backend
Spring
SpringSecurity
April 04, 2024
SecurityBuilder와 SecurityConfigurer

SecurityBuilder와 SecurityConfigurer 본 포스팅 시리즈에서 Spring Security는 Spring Boot 2.7.x 버전을 기준으로한 강의를 최신 스프링 공식 문서를 참고하여 수정하였습니다. Deprecated된 여러 메서드들을 최대한 최신에 맞게 바꾸었지만 완벽하지 않을 수 있습니다. 포인터를 잘 알아야 하는 이유 개념 및 구조 이해 는 빌더 클래스로서 웹 보안을 구성하는 빈 객체와 설정 클래스들을 생성하는 역할을 하며 , 가 있다. 는 Http요청과 관련된 보안처리를 담당하는 필터들을 생성하고 여러 초기화 설정에 관여한다. 는 를 포함하고 있으며 인증 및 인가 초기화 작업은 에 의해 진행된다. 시퀀스 다이어그램 에서 를 호출하면, 의 과 가 호출되어 초기화 작업이 진행된다. 의 가 반환하는 최종 클래스는 내부의 가 반환한 이다. 의 가 반환하는 최종 클래스는 내부의 가 반환한 이다. 는 내부에 을 가지고 있다. 내부의 여러가지 필터들을…

Backend
Spring
SpringSecurity
JWT
April 03, 2024
Spring Security 6.2.1 JWT 설정하기

Spring Security 6.2.1 JWT 설정하기 Security Config 클래스 기본 요소 작성 스프링 시큐리티의 인가 및 설정을 담당하는 클래스이다. Security Config 구현은 스프링 시큐리티의 세부 버전별로 많이 상이하다 (이번 시리즈는 스프링 시큐리티 6.2.1 버전) BCryptPasswordEncoder 등록 커스텀 로직 구현 Form 로그인 방식에서는 클라이언트단이 username과 password를 전송한 뒤 Security 필터를 통과하는데 필터에서 회원 검증을 진행을 시작한다. (회원 검증의 경우 가 호출한 를 통해 진행하며 DB에서 조회한 데이터를 를 통해 받음) 우리의 JWT 프로젝트는 에서 formLogin 방식을 disable 했기 때문에 기본적으로 활성화 되어 있는 해당 필터는 동작하지 않는다. 따라서 로그인을 진행하기 위해서 필터를 커스텀하여 등록해야 한다. 🚀 구현 목표 아이디, 비밀번호 검증을 위한 커스텀 필터() 작성 DB에 …

Backend
Spring
March 23, 2024
Servlet Filter 와 Spring Interceptor

Servlet Filter 와 Spring Interceptor 웹과 관련된 공통 관심사는 AOP를 사용할 수도 있지만 서블릿 필터 또는 스프링 인터셉터를 사용하는 것이 좋다. 웹도 관련된 공통 관심사를 처리할 땐, HTTP의 헤더나 URL의 정보들이 필요한데, 서블릿 필터나 스프링 인터셉터는 를 제공한다. 서블릿 필터 서블릿 필터 흐름 여기서 말하는 서블릿은 스프링 디스패처 서블릿이다. 필터 제한 필터 체인 필터는 순서를 지정하여 자유롭게 구성할 수 있다. 사용예시 LogFilter WebConfig 스프링 인터셉터 스프링 인터셉터 흐름 여기서 말하는 서블릿은 스프링 디스패처 서블릿이다. 스프링 인터셉터 제한 스프링 인터셉터 체인 스프링 인터셉터도 체이닝 기능을 사용할 수 있다. 스프링 인터셉터 인터페이스 서블릿 필터의 경우 단순하게 하나만 제공되나, 인터셉터는 컨트롤러 호출 전(), 호출 후(), 요청 완료 이후()와 같이 단계적으로 잘 세분화 되어 있다. 서블릿 필터의 경우 …

Backend
Spring
March 16, 2024
Bean Validation

Bean Validation Spring Framework에서 제공하는 Validator를 사용하여 로직을 분리하는 방법도 있지만, 본 포스팅에서는 더 편리하고 자주 사용되는 방법인 Bean Validation에 대해 다룬다. Bean Validation 관련 라이브러리 추가가 필요하다. 예제 코드 환경 설정 errors.properties 생성 에 errors 추가하여 errors.properties 등록 User 클래스 , , 의 차이는 다음과 같다. : null값을 허용하지 않는다. : null값과 ""(초기화된 String)을 허용하지 않는다. : null값과 "", ” “를 모두 허용하지 않는다. 와 같이 디폴드 메세지를 지정 가능하다. 추가로 어노테이션도 있는데, 이는 Hibernate에서 제공한다. UserController 클래스 Spring에서 자동으로 빈을 등록해주는 를 Autowired해주기 위해 사용 인자로 받는 에 어노테이션을 추가하여 검증 수행 인…

Backend
Spring
March 13, 2024
Spring 로그(log) 사용 및 레벨 설정

로그 로그를 사용하면 다음 이점이 있다. 쓰레드 정보, 클래스 이름 같은 부가 정보를 함꼐 볼 수 있고, 출력 모양을 조정할 수 있다. 로그 레벨에 따라 개발 서버에서는 모든 로그를 출력하고, 운영서버에서는 출력하지 않는 등 로그를 상황에 맞게 조절할 수 있다. 시스템 아웃 콘솔에만 출력하는 것이 아니라, 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있다. 특히 파일로 남길 떄는 일별, 특정 용량에 따라 로그를 분할하는 것도 가능하다. 성능도 일반 System.out보다 좋다. (내부 버퍼링, 멀티 쓰레드 등등) 그래서 실무에서는 꼭 로그를 사용해야 한다. spring boot 로깅 라이브러리는 slf4j를 사용한다. slf4j는 인터페이스이며, 그 구현체로 spring boot는 logback을 사용한다. 로그 기본 사용법 로그를 출력한다. @Slf4j 롬복(lombok) 어노테이션을 사용하면 Logger 정의 필요없이 바로 다음과 같이 사용 가능하다. 로그 레벨 설정 …

ProjARJS
Spring
March 08, 2024
간단한 좌표 에코 서버

간단한 좌표 에코 서버 프로토타입 테스트 클라이언트 index.html 위도와 경도를 입력받아 을 통해 파일의 함수를 호출한다. 는 서버로부터 받은 데이터를 표시하는데 사용하는 컨테이너이다. ProjectARJS.js : Send 버튼 클릭 시 실행되는 메서드이다. POST 방식으로 서버에 데이터를 보낸다. request body에는 Latitude와 Longitude에 기입한 내용이 json객체로 변환되어 삽입된다. 서버에서는 해당 json 데이터를 받아 그대로 클라이언트에 다시 보낸다. : 서버로부터 성공적으로 데이터를 가져오면 ‘좌표 전송 성공’ 메시지와 함께 실행되는 메서드이다. 응답받은 json데이터를 기반으로 id:echoResponse인 컨테이너에 에코 받은 위도와 경도를 출력한다. 서버 CordinateDTO.java 좌표값을 멤버변수로 가지는 CoordinateDTO 클래스를 정의하였다. 라이브러리를 통해 Getter, Setter 및 생성자(AllArgsCo…

Backend
Spring
November 21, 2023
Meta Annotation이란?

Meta Annotation 김영한님 스프링 강의 복습 중, 위 어노테이션을 사용법이 궁금해서 찾아봤다. 위 어노테이션은 에서 끌어다 썼는데, 무슨의미일까? meta-annotaiton 은 다른 에서도 사용되는 의 경우를 말하며 custom-annotation 을 생성할 때 사용된다. @Target 은 Java compiler 가 annotation 이 어디에 적용될지 결정하기 위해 사용한다. 예를 들어 위에서 사용한 의 ElementType.TYPE 은 “해당 Annotation 은 타입 선언 시 사용한다는 의미”이다. 종류는 다음과 같다. ElementType.PACKAGE : 패키지 선언 ElementType.TYPE : 타입 선언 ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언 ElementType.CONSTRUCTOR : 생성자 선언 ElementType.FIELD : 멤버 변수 선언 ElementType.LOCAL_VARIABLE : 지역…

Backend
Spring
October 02, 2023
Spring Bean 조회하기

Spring Bean 조회하기 Spring을 쓰다보면, Bean이 잘 들어갔는지, 싱글톤이 유지되는지 등 다양한 이유로 Bean을 조회할 일이 많다. 매번 검색으로 찾아봤는데, 일반 빈 조회와 어플리케이션 빈 조회 로직이 헷갈려서 자꾸 까먹는다. 그래서 여기에 Bean 조회 방법을 정리해둔다. JUnit Test로 작성되었다. Spring Bean 조회하기

Backend
Spring
React
July 11, 2023
Spring React간 CORS 이슈 트러블슈팅(WebMvcConfigurer)

Spring React간 CORS 이슈 트러블슈팅 백엔드 Spring, 프론트엔드 React로 풀스택 개발 중, CORS에러를 마주하여 이에 대한 트러블슈팅 기록을 남겨둔다. 기존에는 React를 빌드한 결과물을 Spring의 경로에 넣고 Spring서버를 실행하면 별 다른 이슈가 발생하지 않았는데, 이번에 React와 Spring을 서로 다른 포트에서 개방할 경우, CORS에러가 발생한다. CORS란? Cross-Origin-Resource-Sharing의 약자로 서로 다른 출처에서 리소스를 공유하는 것을 뜻한다. React클라이언트의 경우, GET방식으로 API를 요청할때 다음과 같은 URL을 사용한다.(포트 3000) 이 URL에서 Origin을 나타내는 부분은 Protocol, Host, Port 부분이다. 즉, 과 은 서로 다른 Origin으로 구분된다. 만약 localhost로 테스트한다고 하면, , 은 서로 다른 origin이다. 스프링부트 서버에 http://lo…