Backend/SpringBoot 81

[Spring Security] XSS 방어

XSS 방어는 사용자가 신뢰하는 웹사이트 내에서 악의적인 스크립트가 실행되지 않도록 막는 보안 전략이다. (JS 포함 HTML 등도 해당) 서버에서 설정 할 수 있는 항목은 크게 두가지로 생각해 볼 수 있다. (보통은 서버에서 html을 내려줄 일이 없으므로)CSP (Content Security Policy) 설정이 출처에서 온 리소스만 사용할 수 있도록 하는 설정쿠키 이용시, HttpOnly, Secure 설정 CSP 설정 예httpSecurity의 header 에 추가하는 설정스크립트, 이미지 등의 출처를 명시해 두어, 해당 출처로 부터 온 데이터들만 사용 할 수 있도록 한다.공백이 매우 중요하다. 하나의 설정이 끝나는 지점에 ; 를 적어두고 공백을 하나 띄워야 한다.연속된 설정의 경우 다음 항..

Backend/SpringBoot 2026.02.11

[Entity] GeneratedValue 대신 TSID 사용하기

보통 Entity를 구성할 때 id 필드 값에 아래의 어노테이션을 사용할 때가 많다.@GeneratedValue(strategy = GenerationType.IDENTITY) 이 경우, DB의 DDL 에도 아래와 구성을 해 주어야 한다.id BIGINT GENERATED BY DEFAULT AS IDENTITY 의미 부터 보자면, db에 값을 저장할때 id 값을 db 에서 자동으로 생성하여 증가 해주는것을 의미한다. (JPA에서 해주지 않는다) 이 경우 다음의 문제점이 발생한다.대량의 bulk insert가 필요 할 때 bulk 동작을 JPA 및 hibernate가 수행하지 않고, 건별로 insert 쿼리를 날린다.속도가 엄청나게 느리고 과부하가 걸린다.데이터 1개를 입력 -..

Backend/SpringBoot 2026.02.10

OAuth 연동

모바일일 경우에는 OAuth 연동을 모바일쪽에서 직접 구현 -> 해당 정보를 백앤드로 전달 해주었다. 웹페이지의 경우에도 그렇게 할 수 있으나 클라이언트 측에 키값이 존재한다는 점이 불안 요소가 있다. (물론 이를 보완할 수도 있다. 키값만 db에 저장한다든지, 서버가 전달 해준다든지 등등) 서버에서 OAuth를 연동할 경우 장점은,키값 안전하게 보호각기 다른 플랫폼에 OAuth 연동해도 연동이 일괄적으로 간편이부분은 클라이언트 쪽에선 진짜...하나 추가될 때 마다 괴로웠음스프링부트에서는 설정만 추가하고 필요하면 코드만 살짝 바꾸면 된다. 일단, 구글 기준으로 스프링부트에서 연동하는 내용을 정리해 둔다. 우선순위 부터 보자면각 플랫폼의 dev 사이트에서 프로젝트 생성프로젝트에서 OAuth 연동을 위한 ..

Backend/SpringBoot 2026.02.06

Cursor 기반 Paging 추가 정리(QueryDsl 기준)

https://dean83.tistory.com/285 여기에서 Paging 에 대한걸 간략하게 정리 하였다. 그러나 실제로는 Cursor 기반을 많이 사용하기도 하고, 좀 더 까다롭기도 하다. 이 부분 또한 위의 페이지에 정리 하려 하다가 너무 복잡해져 따로 정리한다.예는 유저를 pageing 하는 예 이다. 중요한 내용 정리 먼저, 엔티티에 1:N, N:M 등 List 형태의 컬럼이 있을경우 해당 테이블과 fetch join을 하면 안된다. fetch join으로 인해 row의 갯수가 증가해 버린다 -> limit에 의해 의도치 않은 데이터 갯수가 생성된다.예 ) 유저 조회가 메인인 경우, 유저에 roles 라는 List 컬럼이 있을경우동일 유저인데 role이 다를 경우 row 갯수 증가 -> 그러..

Backend/SpringBoot 2026.02.03

임시 비번 발급 후 비교할때 주의점(PasswordEncoder)

실제 회원가입 등 비밀번호 저장을 DB에 할 때에는 PasswordEncoder 의 encode 메서드를 이용해서 저장만 하지, 실제 비교할 일은 거의 없었다. 보통은 이미 구현이 되어 있는 DaoAuthenticationProvider 에서 인증을 해주기 때문이다. 임시번호 발급시 다양한 방법으로 확인 및 구현이 가능하겠으나, 현재 나의 경우는 DaoAuthenticationProvider 을 상속받아 구현하는 구현체를 만들어서 이곳에서 비교를 해야 하는 상황이다.(만일 아이디 / 비번이 아닐경우 다른 Provider를 사용할 수 있고, 이 경우, AuthenticationManager 구현체를 디버깅 걸어서 확인필요) 알맞게 임시 비밀번호를 발급하고 입력했음에도 계속하여 로그인 실패가 나서 그 이..

Backend/SpringBoot 2026.02.02

Hexagonal Architecture 일부적용 및 느낀점

스프링부트를 하면서, Hexagonal Architecture 에 대한 고민을 했던 기억이 있어 내용을 정리해 둔다. 고민시점도메인 위주로 패키지를 나누어 둠 (혹시 모를, 추후 MSA 전환을 대비)도메인 A 에서 도메인 B의 Service나 Repository를 주입받아 이용하는곳이 있었음. 이 연관관계를 깨고 싶었음. 이 시점에 고민을 했었고, 실제 완전한 Hexagonal 은 아니어도, 어느정도 의미있게 분리를 했다고 생각한다. 서버 이벤트 방식 고민자료를 리턴받는 콜백 개념이 필요했으므로, fire-forget인 이벤트와는 맞지않다고 생각했다.충분히 큰 규모였다면 kafka 나 MQ 처럼 외부 서비스를 구성해 볼수도 있겠지만, 현재는 시작단계여서 오버스펙이었다.또한 백앤드는 클라이언트와 다르게..

Backend/SpringBoot 2026.01.30

Application.yaml 값 불러오기 (Class에 매핑)

어딘가에 기록을 해 둔거 같은데...찾을수가 없어서 다시 기록해 둔다. 다양한 방법으로 yaml 에 있는 값을 불러올 수 있으나, 여기서는 Class 혹은 Record에 매칭 하는 방법을 기준으로 정리해둔다. application.yaml에 다음과 같이 정의되어 있다면, ...jwt: secret: ${JWT_SECRET_KEY} access_key_expiration: 600000 refresh_key_expiration: 1209600000 issuer: "test-server"... 아래와 같이 클래스 및 맴버변수로 매핑할 수 있다. @Getter@Setter@Configuration@ConfigurationProperties(prefix = "jwt")public class JwtProp..

Backend/SpringBoot 2026.01.29

Cache, RefreshToken 용 Redis를 쓸 경우.

Redis를 통해 Cache와 RefreshToken을 둘다 관리하는 경우, 설정이 헷갈릴 수 있어 정리해 둔다. 일단 요약하자면, 1개의 Redis를 띄워 각각 cache, token용으로 나누어 운용 가능단, database를 나누어야 함.예 : 0번은 cache용, 1번은 token용기본적으로 0 ~ 15까지 제공application.yaml 설정을 통해 둘중 하나의 config는 자동으로, 하나의 config는 수동으로 설정해야 함. 둘중 무얼 수동으로 설정할 지는 자유이다.수동으로 설정할때 주의점은, bean 이름을 반드시 명시해야 한다는 점이다.기본 bean 으로 사용할 경우 application.yaml의 설정을 덮어 쓴다RefreshToken 용 config 수동 설정 예@Configur..

Backend/SpringBoot 2026.01.29

Security 에서 Role 적용시 헷갈리는 부분 정리

보통, User의 Role을 이용할 경우, enum을 통해서 ADMIN, USER 처럼 정의하고 이용하게 된다. DB에도 이렇게 저장된다.그러나 권한 확인 메소드인 hasRole 같은 경우에는 자동으로 앞에 "ROLE_" 문자열을 붙여서 비교하게 된다. 사용자 인증 할때 보통 Custom 한 UserDetails 를 구현한 구현체 구성을 하게 되는데, 오버라이드 한 메소드 중 아래 메소드에서"ROLE_" 문자열을 붙여줘야 한다.@Overridepublic Collection getAuthorities() { if(userDto == null) return List.of(); return List.of(new SimpleGrantedAuthority("ROLE_" + userDto..

Backend/SpringBoot 2026.01.28

SSE 예제

이론부분은 https://dean83.tistory.com/412 이부분을 보면 된다. 별도로 build.gradle에 추가할 필요는 없다. (대부분 starter-web은 이미 추가 되어 있다) Async 및 TaskExecutor 설정이 부분은 https://dean83.tistory.com/393 에서 자세히 다루었다.@Configuration@EnableAsync@EnableSchedulingpublic class AsyncConfig { @Bean("sseExecutor") public TaskExecutor sseTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); e..

Backend/SpringBoot 2026.01.14