QueryDSL 활용과 프로젝트 설정 가이드
QueryDSL을 활용하려면 Q파일이 필요하다.
Q파일 생성 방법
Gradle Task에서 Tasks → other → compileJava
실행한다.
주의사항
엔티티 작성 후 바로 Q파일을 생성하는 것이 좋다. 컴파일 에러가 있으면 Q파일 생성이 불가하다.
Spring Boot 3.x의 변경 사항
jakarta.persistence
의존성을 사용해야 한다.
엔티티와 패키지 구조 설계
엔티티는 core
패키지에 저장한다. 다른 파일들은 복수형으로 패키지 이름 설정하여 모아둔다. (ex: orders
, products
)
리스트 검색
쿼리DSL을 사용하면 조건 검색과 페이징을 조건 검색과 페이징을 한 번에 처리할 수 있다.
주의사항
- 데이터가 많을 경우 성능 저하를 방지하려면 Full Searching은 지양해야 한다.
- 반드시
max
값 설정한다. QueryDSL이 아니더라도 페이징 또는limit
적용은 필요하다. - 사용자가 비정상적인 값을 요청할 경우 이를 차단하는 방어 로직이 필수이다.
트랜잭션과 권한 관리
주요 오퍼레이션에는 가급적 @Transactional
설정 권장한다.
권한 관리
- 권한은 String 대신 Enum으로 설계한다.
- 특정 숫자로 대신 설정하여 DB 성능 상의 이점을 챙길 수 있다.
- 하지만 대규모 서비스가 아니라면 가독성을 위해 텍스트로 표현하는 것이 좋다.
데이터 조회 최적화
반복적인 DB 호출 대신 여러 데이터를 한 번에 조회하는 효율적인 방안을 모색하는 것이 좋다.
MSA 환경에서의 데이터 일관성 문제
한 서비스의 데이터 변경이 다른 서비스에 반영되지 않을 수 있는 단점이 있다.
대응 방법
데이터 불일치 방지를 위한 방어 로직을 추가해주어야 한다.
JWT 사용과 보안 관련 가이드
JWT와 세션 방식 비교
세션 방식
서버 관리로 보안 컨트롤에 용이하다. 하지만 서버 과부하 발생 시 전체 사용자가 영향을 받음.
JWT
서버 간 시크릿키만 공유하면 돼서 확장성이 우수하다.
주의사항
- 표준화된 방식이라 암호화 강도가 낮다.
- 클레임에 권한 정보를 포함할 경우 보안 취약 가능성 있다.
JWT 보안 강화 방안
- 탈취된 토큰 차단
- 블랙리스트를 만들어 별도로 차단한다.
- Refresh Token
- Access Token에 짧은 만료기간을 적용한다.
- Access Token 재발급을 위해 Refresh Token을 키로 활용한다.
- 추가 인증 정보
- 실제 기업에서는 토큰의 취약점을 보완하기 위해 IP, 디바이스 정보 등과 연계해 관리한다. 이때는 JWT 강점이 많이 소실된다.
CSRF와 하이재킹
- 간편하게 클라이언트의 정보를 같이 대조하는 CSRF 기술이 있다.
- JWT나 세션 방식이나 하이재킹을 당하게 되면 어쩔수 없는 부분이다.
- 그래서 그것을 막기 위한 통신 암호화같은 기술이 발전하고 있다.
권한 정보 관리
권한과 같은 인사 데이터는 가변성이 낮은 정보이기 때문에 Redis 같은 인메모리 DB에 저장해 효율적으로 관리하는 것이 좋겠다.
JWT 관련 질문과 답변
Q&A 정리
Q1. JWT를 사용하면 보안상 어떤 장점이 있나?
A1. Stateless의 장점이 가장 크며, 아이디/비밀번호의 반복 노출을 방지한다.
- 만료 기간은 피해 범위를 줄이는 보조적 역할을 한다.
- Access Token은 짧은 만료 기간, Refresh Token은 재발급 키로 활용한다.
Q2. 클라이언트에 인증 책임을 넘기는 방식이 아닌가?
A2. 클라이언트에게 일정 부분 책임을 위임하는 방식이다. 그래서 중요한 정보는 JWT 외부에서 별도 관리해야 한다.
Q3. 최소 정보만 JWT로 관리하고 권한은 DB에서 검증하는 방식은 어떤가?
A3: 하이브리드 접근은 좋은 방법이다. 사용자 ID, 권한을 JWT로 관리하되, 관리자 권한은 추가로 DB에서 검증하는 것은 효율적인 접근이다.